{"openapi":"3.1.1","paths":{"/admins":{"get":{"description":"Return the list of admin users for your company. Each entry is either an employee (with an id) or an external user (with its userId, the id a ticket carries for an EXTERNAL_ADMIN actor). roleName is the Clerk role key.","operationId":"getAdmins","parameters":[],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetAdmins_Output"}}}}},"summary":"Get all admins","tags":["Admins"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/admins/email":{"post":{"description":"Send an email to the admins of your company. Recipients can only be admins of your own company: either the ones named in adminIds, or all of them when adminIds is omitted. There is no way to email any other address.","operationId":"sendEmailToAdmins","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendEmailToAdminsBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendEmailToAdmins_Output"}}}}},"summary":"Email the company admins","tags":["Admins"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/company":{"get":{"description":"Return the company associated with the API key. Only accessible with a Company API key.","operationId":"getMyCompany","parameters":[],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetMyCompany_Output"}}}}},"summary":"Get the authenticated company","tags":["Company"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/company/metrics":{"get":{"description":"Return the KPI report of the authenticated company as JSON: use it to summarise the company's situation, build a report or answer how-many questions at a glance. `report` holds the headline counts (devices in use, assigned or not, and in stock; employees to enroll or enrolled; devices with MDM on, off or in another MDM; compliance issues; disk encryption; EDR; online and offline devices; employees to onboard and to offboard), each next to the cockpit table that lists them, and leaves out a count equal to 0. `companyMetrics` holds every raw counter the report is built from, zeros included, plus the connected apps and the SaaS identities. Through MCP, the counters of a domain the caller cannot read (equipment, employees, SaaS) are left out of `report` and null in `companyMetrics`. These are counts only: to list the devices, employees, onboardings or offboardings behind a count, use `getDevices`, `getEmployees`, `getOnboardings` or `getOffboardings` instead; for the compliance issues themselves, use `getComplianceAlerts`. Only accessible with a Company API key.","operationId":"getCompanyMetrics","parameters":[],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetCompanyMetrics_Output"}}}}},"summary":"Get the company metrics report","tags":["Company"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/custom-fields":{"get":{"description":"Return a paginated list of custom field definitions for your company — definitions only, without the values stored on entities. To read or write the values on a specific entity, use `getDeviceCustomFields`/`getDevicesCustomFields` (devices) or `getAccessoryCustomFields` (accessories). Defaults to ACTIVE fields when no status filter is supplied. A custom field definition can apply to one or more entity types — device, order, employee, or accessory — via its `applyTo` field.","operationId":"listCustomFields","parameters":[{"name":"status","required":false,"in":"query","style":"deepObject","explode":true,"schema":{"type":"object"},"description":"Filter by status, e.g. status[operationType]=INCLUDE&status[values][]=ACTIVE"},{"name":"fieldType","required":false,"in":"query","style":"deepObject","explode":true,"schema":{"type":"object"},"description":"Filter by field type, e.g. fieldType[operationType]=INCLUDE&fieldType[values][]=TEXT"},{"name":"applyTo","required":false,"in":"query","style":"deepObject","explode":true,"schema":{"type":"object"},"description":"Filter by target entity type, e.g. applyTo[operationType]=INCLUDE&applyTo[values][]=DEVICE&applyTo[values][]=EMPLOYEE"},{"name":"searchTerm","required":false,"in":"query","description":"Filter custom fields by label","schema":{"type":"string"}},{"name":"count","required":false,"in":"query","description":"Number of items per page (default 50, max 200)","schema":{"type":"number"}},{"name":"page","required":false,"in":"query","description":"Page number (default 1)","schema":{"type":"number"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListCustomFieldsResponse_Output"}}}}},"summary":"List custom fields","tags":["CustomFields"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}},"post":{"description":"Create a new custom field definition. Labels are not constrained to be unique. Options are only allowed for SELECT and MULTI_SELECT field types.","operationId":"createCustomField","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomFieldBody"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomFieldResponse_Output"}}}}},"summary":"Create a custom field","tags":["CustomFields"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/custom-fields/{customFieldId}":{"get":{"description":"Return the custom field definition for the given custom field ID — the definition only, not the values stored on entities. To read or write values, use the per-entity endpoints (`getDeviceCustomFields`, `getAccessoryCustomFields`, …).","operationId":"getCustomField","parameters":[{"name":"customFieldId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomFieldResponse_Output"}}}}},"summary":"Get a custom field by ID","tags":["CustomFields"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}},"patch":{"description":"Update label, applyTo (widen-only), optionsToAdd, or optionsToRename on a custom field. At least one field must be provided. Archived fields cannot be updated.","operationId":"updateCustomField","parameters":[{"name":"customFieldId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCustomFieldBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomFieldResponse_Output"}}}}},"summary":"Update a custom field","tags":["CustomFields"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/custom-fields/{customFieldId}/archive":{"post":{"description":"Archive a custom field definition. Archived fields are no longer offered for new values but remain readable. Returns 409 if the field has active consumers (related entities must be cleared first).","operationId":"archiveCustomField","parameters":[{"name":"customFieldId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomFieldResponse_Output"}}}}},"summary":"Archive a custom field","tags":["CustomFields"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/workspace/companies":{"get":{"description":"Return the list of companies in your workspace. Only accessible with a Workspace API key.","operationId":"getCompanies","parameters":[{"name":"page","required":false,"in":"query","description":"Page number","schema":{"minimum":1,"maximum":9007199254740991,"default":1,"type":"number"}},{"name":"perPage","required":false,"in":"query","description":"Number of items per page (max 100)","schema":{"minimum":1,"maximum":100,"default":50,"type":"number"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetCompanies_Output"}}}}},"summary":"Get all companies in the workspace","tags":["Workspace"],"x-primo-access-level":"read","x-primo-access-scope":["workspace"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Workspace","className":"badge-workspace","color":"#6366F1"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-workspace\">Scope: Workspace</span>"}},"post":{"description":"Create a company in your workspace as a draft. Nothing is provisioned yet: configure its options, then activate it. The name must be unique across Primo and the domain unique within your workspace. Only accessible with a Workspace API key.","operationId":"createCompany","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCompanyBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetCompany_Output"}}}}},"summary":"Create a company in the workspace","tags":["Workspace"],"x-primo-access-level":"write","x-primo-access-scope":["workspace"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Workspace","className":"badge-workspace","color":"#6366F1"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-workspace\">Scope: Workspace</span>"}}},"/workspace/companies/{companyId}":{"get":{"description":"Return the company details for the given company ID, including its status and its subscription options. Answers for a company that is still a draft. Only accessible with a Workspace API key.","operationId":"getCompany","parameters":[{"name":"companyId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetCompany_Output"}}}}},"summary":"Get a company by ID","tags":["Workspace"],"x-primo-access-level":"read","x-primo-access-scope":["workspace"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Workspace","className":"badge-workspace","color":"#6366F1"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-workspace\">Scope: Workspace</span>"}}},"/workspace/companies/{companyId}/options":{"patch":{"description":"Update the subscription options of a company that has not been activated yet. Only the fields you send are changed. Activation closes this endpoint: an activated company answers 409 and its configuration is then managed from the Primo cockpit. Only accessible with a Workspace API key.","operationId":"updateCompanyOptions","parameters":[{"name":"companyId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCompanyOptionsBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetCompany_Output"}}}}},"summary":"Update the options of a draft company","tags":["Workspace"],"x-primo-access-level":"write","x-primo-access-scope":["workspace"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Workspace","className":"badge-workspace","color":"#6366F1"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-workspace\">Scope: Workspace</span>"}}},"/workspace/companies/{companyId}/activate":{"post":{"description":"Activate a draft company: it becomes usable, its administrators are granted access, and it starts being billed according to its options. Irreversible, and the options can no longer be changed through the API afterwards. Only accessible with a Workspace API key.","operationId":"activateCompany","parameters":[{"name":"companyId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetCompany_Output"}}}}},"summary":"Activate a draft company","tags":["Workspace"],"x-primo-access-level":"write","x-primo-access-scope":["workspace"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Workspace","className":"badge-workspace","color":"#6366F1"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-workspace\">Scope: Workspace</span>"}}},"/devices":{"get":{"description":"**Deprecated** — use `getDevices` (`POST /devices/search`) instead, which returns the same device objects and additionally accepts a filter and a free-text search. This route will be removed on 2026-11-01. Return the paginated list of devices for your company, retired ones excluded, as JSON.","operationId":"listDevicesUnfiltered","parameters":[{"name":"page","required":false,"in":"query","description":"Page number","schema":{"minimum":1,"maximum":9007199254740991,"default":1,"type":"number"}},{"name":"perPage","required":false,"in":"query","description":"Number of items per page (max 100)","schema":{"minimum":1,"maximum":100,"default":50,"type":"number"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetDevices_Output"}}}}},"summary":"Get all devices (deprecated)","tags":["Devices"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}},"post":{"description":"Create a new device in your company.","operationId":"createDevice","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeviceBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetDevice_Output"}}}}},"summary":"Create a device","tags":["Devices"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}},"patch":{"description":"Update the inventory data of MULTIPLE devices in one call — the batch form of `updateDevice`, with the same fields and the same rules per device. Provide a list of `items`, each targeting one `deviceId` (up to 100 per call, each device at most once). Writes are independent and best-effort: the call returns 200 with a `results` manifest reporting `ok` / `error` per device — always inspect `results` rather than relying on the HTTP status to detect partial failures. Prefer this over calling `updateDevice` once per device; use `updateDevice` for a single device, when you want the updated device back or a failure to surface as an HTTP error.","operationId":"updateDevices","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateDevicesBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateDevicesResult_Output"}}}}},"summary":"Update several devices","tags":["Devices"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/devices/export":{"get":{"description":"Export the devices of your company as a paginated CSV (one row per device, first line is the header, up to 1000 devices per page). To send an inventory of devices and the employees holding them, with no device code, use `exportInventory` instead. Each row contains the device attributes (IMEIs included, `|`-separated in `imeis`), its latest code of each type (recovery key, iCloud bypass code, unlock PIN, recovery OS password — see `getDeviceCodeHistory` for the full history), and one `customField.<label>` column per active custom field (SELECT / MULTI_SELECT values are resolved to their option labels). Iterate `page` until `totalPages` and concatenate the CSV pages (dropping the header line of subsequent pages) to rebuild the full export. The REST route responds with `text/csv` (pagination in the `X-Page`, `X-Per-Page`, `X-Total-Pages` and `X-Total-Elements` headers); the MCP tool returns the CSV in the `csv` field.","operationId":"exportDevices","parameters":[{"name":"page","required":false,"in":"query","description":"Page of devices to export (1-indexed)","schema":{"minimum":1,"maximum":9007199254740991,"default":1,"type":"number"}},{"name":"perPage","required":false,"in":"query","description":"Number of devices per CSV page (default 500, max 1000)","schema":{"minimum":1,"maximum":1000,"default":500,"type":"number"}}],"responses":{"200":{"description":"CSV page, one row per device. Pagination is returned in the X-Page, X-Per-Page, X-Total-Pages and X-Total-Elements response headers.","content":{"text/csv":{"schema":{"type":"string"}}}}},"summary":"Export devices as CSV","tags":["Devices"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/devices/inventory/export":{"get":{"description":"Export the inventory of your company as a paginated CSV of devices and the employees holding them, up to 1000 rows per page. It carries no device code (recovery key, unlock PIN, bypass code, password) and no personal email, phone or address, so the file can be sent outside IT. To export every device attribute, its custom fields and its latest codes, use `exportDevices` instead. One row per device in use or in stock (retired devices are left out) with the employee it is assigned to, plus one row per active employee holding no device. Columns, always in this order: Employee first name, Employee last name, Employee email, Employee status, Device name, Device type, Model, Serial number, Device status (in use, in stock), Enrollment status (enrolled, unenrolled, never enrolled), Last check-in, Purchase date. Employee status is left when the end date has passed or the offboarding is finished, not started when the start date is ahead, leaving when an end date is set or an offboarding is in progress, active otherwise. A missing value is an empty cell. Rows are sorted by employee last name then first name, devices assigned to nobody last. `totals.deviceRows` is the number of devices in use or in stock. Iterate `page` until `totalPages` and concatenate the CSV pages, dropping the header line of every page after the first. The REST route responds with `text/csv` (pagination in the `X-Page`, `X-Per-Page`, `X-Total-Pages` and `X-Total-Elements` headers); the MCP tool returns the CSV in the `csv` field.","operationId":"exportInventory","parameters":[{"name":"page","required":false,"in":"query","description":"Page of rows to export (1-indexed)","schema":{"minimum":1,"maximum":9007199254740991,"default":1,"type":"number"}},{"name":"perPage","required":false,"in":"query","description":"Number of rows per CSV page (default 500, max 1000)","schema":{"minimum":1,"maximum":1000,"default":500,"type":"number"}}],"responses":{"200":{"description":"CSV page of the inventory. Pagination is returned in the X-Page, X-Per-Page, X-Total-Pages and X-Total-Elements response headers.","content":{"text/csv":{"schema":{"type":"string"}}}}},"summary":"Export the device and employee inventory as CSV","tags":["Devices"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/devices/filters-options":{"get":{"description":"Return every criterion a device filter accepts — each with its `key`, `valueType`, allowed operations and live company values — plus the custom fields defined for devices. This is the vocabulary for `getDevices`: use a criterion's `key` as the filter key and one of its `values` inside the clause (`{\"<key>\":{\"operationType\":\"INCLUDE\",\"values\":[\"<value>\"]}}`). Call this first whenever you are unsure a criterion exists — `getDevices` rejects an unknown key with 400. To build a device group `target` instead, use `getDeviceGroupFiltersOptions`: device groups accept a deliberately narrower set of criteria, because a group targeting a volatile criterion would change population daily.","operationId":"getDeviceFilterCatalog","parameters":[],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetDeviceFilterCatalog_Output"}}}}},"summary":"Get the device search filter catalog","tags":["Devices"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/devices/{deviceId}":{"get":{"description":"Return the device details for the given device ID, including its `imeis` (IMEIs, digits only, one per SIM slot, reported for company-owned iPhones, cellular iPads and Android phones), which `getDevices` leaves out. This device can have custom fields (see `getDeviceCustomFields`) and code history (see `getDeviceCodeHistory`). This device can also have local user accounts (see `getDeviceUsers`).","operationId":"getDevice","parameters":[{"name":"deviceId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetDevice_Output"}}}}},"summary":"Get a device by ID","tags":["Devices"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}},"patch":{"description":"Update the inventory data of one device: its assignee, its identity and specs, and its purchase data. Only the fields present in the body are changed — each field documents its own constraints. Fields that MDM reports for an enrolled device can only be set while the device is not enrolled; changing one on an enrolled device is rejected (409), and so is a name driven by a device naming MDM control. Sending a field with its current value is always accepted, so a read-modify-write of the whole device is safe. Use `updateDeviceTags` for tags and `updateDeviceOwner` to only reassign the device.","operationId":"updateDevice","parameters":[{"name":"deviceId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateDeviceBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetDevice_Output"}}}}},"summary":"Update a device","tags":["Devices"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}},"delete":{"description":"Permanently delete a device from your company. The device must not be enrolled.","operationId":"deleteDevice","parameters":[{"name":"deviceId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteDevice_Output"}}}}},"summary":"Delete a device","tags":["Devices"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/devices/{deviceId}/lock":{"post":{"description":"Lock the device for the given device ID.\n\n**Supported platforms:** macOS, Windows, Linux\n\n**Important:** The lock command will be executed the next time the device comes online.\n\n**Platform-specific behavior:**\n- **macOS**: Locks the device with a 6-digit PIN. The PIN is stored and can be retrieved via the unlock endpoint.\n- **Windows/Linux**: Locks the device without a PIN.\n\n**Not supported:** iOS, Android, Chrome OS","operationId":"lockDevice","parameters":[{"name":"deviceId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LockDevice_Output"}}}}},"summary":"Lock a device","tags":["Devices"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/devices/{deviceId}/unlock":{"post":{"description":"Unlock the device for the given device ID.\n\n**Supported platforms:** macOS, Windows, Linux\n\n**Platform-specific behavior:**\n- **macOS**: Returns the 6-digit unlock PIN that was generated during the lock operation. The user must enter this PIN manually on the device to unlock it.\n- **Windows/Linux**: Sends an unlock command to the device.\n\n**Not supported:** iOS, Android, Chrome OS","operationId":"unlockDevice","parameters":[{"name":"deviceId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnlockDevice_Output"}}}}},"summary":"Unlock a device","tags":["Devices"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/devices/{deviceId}/wipe":{"post":{"description":"Wipe the device for the given device ID.\n\n**Supported platforms:** macOS, iOS, Windows, Linux\n\n**Platform-specific behavior:**\n- **Windows**: Accepts optional `wipeType` parameter:\n  - `SOFT` (default): Attempts to wipe the device once. If it fails, the device reboots to its initial state.\n  - `HARD`: Attempts to wipe the device repeatedly until successful.\n    - ⚠️ **Warning:** If the wipe keeps failing, this can leave the device in an unusable state, requiring a reinstallation via USB key.\n- **macOS/iOS/Linux**: Performs a full device erase. The `wipeType` parameter is ignored.\n\n**Not supported:** Android, Chrome OS","operationId":"wipeDevice","parameters":[{"name":"deviceId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WipeDeviceBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WipeDevice_Output"}}}}},"summary":"Wipe a device","tags":["Devices"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/devices/{deviceId}/run-script":{"post":{"description":"Run a script on the device for the given device ID. Pass `{ \"scriptId\": 12 }` to run a saved script (see `getScripts`), or `{ \"contents\": \"...\" }` to send the source inline.\n\nThis is the single-device shortcut for `runScript`; use that one to target all devices, device groups, or several devices at once. The platforms are derived from the device, so a script whose interpreter does not match it is rejected.\n\nThe response returns immediately with the execution `pending`; poll `getDeviceScriptExecutions` or `getScriptRun` for the outcome.\n\n⚠️ **This executes arbitrary code on the device with elevated privileges, and is not idempotent** — repeating the call runs the script again. Review the script before calling.\n\n**Supported platforms:** macOS (shell/Python), Windows (PowerShell), Linux (shell/Python). Not supported: iOS, Android, ChromeOS.","operationId":"runDeviceScript","parameters":[{"name":"deviceId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunDeviceScriptBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunScript_Output"}}}}},"summary":"Run a script on one device","tags":["Devices"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/devices/{deviceId}/script-executions":{"get":{"description":"Return the paginated script executions that reached this device, newest first — across every run, including company-wide and device-group runs launched elsewhere. Each entry carries the script that ran plus its status, output, exit code and runtime. Use this to answer \"what has been run on this machine?\".\n\nFor the per-device results of one specific run, use `getScriptRunExecutions`. For the list of runs themselves, use `getScriptRuns`.\n\nExecutions are reconciled with FleetDM by a background sweep that runs every 15 minutes, so a freshly created run reads back as `pending` until the next sweep. Poll no more often than that.","operationId":"getDeviceScriptExecutions","parameters":[{"name":"deviceId","required":true,"in":"path","schema":{"type":"string"}},{"name":"page","required":false,"in":"query","description":"Page number","schema":{"minimum":1,"maximum":9007199254740991,"default":1,"type":"number"}},{"name":"perPage","required":false,"in":"query","description":"Number of items per page (max 100)","schema":{"minimum":1,"maximum":100,"default":50,"type":"number"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetDeviceScriptExecutions_Output"}}}}},"summary":"List a device's script history","tags":["Devices"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/devices/{deviceId}/retire":{"post":{"description":"Retire (decommission) a device: it is unassigned from its owner, renamed to `deviceName`, marked retired and taken out of stock, with `condition` and `notes` recorded; `putDeviceBackInStock` reverts it. The device must not be enrolled in MDM: an enrolled device is refused with 409, but the unassignment and rename are applied before that check and are kept, so disenroll it first (`disenrollDevice`) and wait until it no longer reads as enrolled. When the company has MDM, `dataAction` WIPE, SOFT_WIPE or HARD_WIPE sends a wipe; LOCK, NOTHING or no value sends a disenroll instead — no lock command is sent. A wipe needs the MDM host record that a completed disenrollment removes: without it the call fails with 502 after the retirement is recorded.","operationId":"retireDevice","parameters":[{"name":"deviceId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetireDeviceBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetireDevice_Output"}}}}},"summary":"Retire a device","tags":["Devices"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/devices/{deviceId}/reboot":{"post":{"description":"Trigger a reboot on the device. The command is sent the next time the device comes online.","operationId":"rebootDevice","parameters":[{"name":"deviceId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RebootDevice_Output"}}}}},"summary":"Reboot a device","tags":["Devices"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/devices/{deviceId}/disenroll":{"post":{"description":"Disenroll the device from MDM; once done, the device is no longer managed. Android is disenrolled immediately. On macOS, Windows and Linux a removal script runs when the device next checks in, so it still reads as enrolled until then; other platforms cannot be disenrolled remotely and are refused with 502. A device with no MDM host record is only marked disenrolled. It cannot be undone from the API — the device has to enroll again (see `sendEnrollmentRequest`). `retireDevice` and `deleteDevice` require a device that is no longer enrolled.","operationId":"disenrollDevice","parameters":[{"name":"deviceId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DisenrollDevice_Output"}}}}},"summary":"Disenroll a device","tags":["Devices"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/devices/{deviceId}/move-to-stock":{"post":{"description":"Move the device to stock (unassign it from any employee).","operationId":"moveDeviceToStock","parameters":[{"name":"deviceId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MoveToStock_Output"}}}}},"summary":"Move a device to stock","tags":["Devices"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/devices/{deviceId}/move-to-in-use":{"post":{"description":"Move the device from stock back to in-use status.","operationId":"moveDeviceToInUse","parameters":[{"name":"deviceId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MoveToInUse_Output"}}}}},"summary":"Move a device to in-use","tags":["Devices"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/devices/{deviceId}/put-back-in-stock":{"post":{"description":"Cancel a pending retirement and return the device to stock.","operationId":"putDeviceBackInStock","parameters":[{"name":"deviceId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PutBackInStock_Output"}}}}},"summary":"Put a device back in stock","tags":["Devices"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/devices/{deviceId}/owner":{"post":{"description":"Assign or unassign a device to an employee. Pass null to unassign.","operationId":"updateDeviceOwner","parameters":[{"name":"deviceId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateDeviceOwnerBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateDeviceOwnerResponse_Output"}}}}},"summary":"Update a device owner","tags":["Devices"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/devices/{deviceId}/tags":{"post":{"description":"Replace the tags on a device with the provided list.","operationId":"updateDeviceTags","parameters":[{"name":"deviceId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateDeviceTagsBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateDeviceTagsResponse_Output"}}}}},"summary":"Update device tags","tags":["Devices"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/devices/{deviceId}/events":{"get":{"description":"Return the list of lifecycle events recorded by Primo for the given device (lock, wipe, reboot, disenroll, etc.) in reverse chronological order. For the MDM activity feed reported by the MDM layer, use `getDeviceActivities`; for raw MDM protocol commands and their delivery status, use `getDeviceCommands`.","operationId":"getDeviceEvents","parameters":[{"name":"deviceId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetDeviceEvents_Output"}}}}},"summary":"Get device events","tags":["Devices"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/devices/{deviceId}/users":{"get":{"description":"Return the local user accounts provisioned on ONE device, each with its privilege level (`rights`: ADMIN / USER / UNKNOWN). Use this to find which accounts hold local administrator or standard user rights on a machine. For many devices at once, use `getDevicesUsers` instead of calling this endpoint in a loop.","operationId":"getDeviceUsers","parameters":[{"name":"deviceId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetDeviceUsers_Output"}}}}},"summary":"List local user accounts on a device","tags":["Devices"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/devices/users":{"post":{"description":"Return the local user accounts provisioned on MULTIPLE devices in one call, grouped by device id, each account with its privilege level (`rights`: ADMIN / USER / UNKNOWN). Use this to answer fleet-wide questions such as \"which users hold local administrator rights on their machine\": list the devices with `getDevices`, then pass their ids here. Provide a list of `deviceIds` (up to 200 per call). Prefer this over calling `getDeviceUsers` once per device.","operationId":"getDevicesUsers","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetDevicesUsersBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetDevicesUsers_Output"}}}}},"summary":"List local user accounts on multiple devices","tags":["Devices"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/devices/{deviceId}/code-history":{"get":{"description":"Return the decrypted code history for ONE device (recovery key, iCloud bypass code, unlock PIN, recovery OS password), newest first. Optionally filter by `type`. For many devices at once, use `getDevicesCodeHistory` instead of calling this endpoint in a loop.","operationId":"getDeviceCodeHistory","parameters":[{"name":"deviceId","required":true,"in":"path","schema":{"type":"string"}},{"name":"type","required":false,"in":"query","description":"Filter to a single code type (ICLOUD_BYPASS_CODE, UNLOCK_PIN, RECOVERY_KEY, RECOVERY_OS).","schema":{"enum":["ICLOUD_BYPASS_CODE","UNLOCK_PIN","RECOVERY_KEY","RECOVERY_OS"],"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetDeviceCodeHistory_Output"}}}}},"summary":"Get device code history","tags":["Devices"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/devices/{deviceId}/reachability":{"get":{"description":"Return how reachable ONE device was over the last 7 days, from the Fleet online status recorded at each 30-minute sync: `reachabilityPercent` (share of the syncs that saw the device online, 0 to 100, null when no sync recorded it yet) and `samples` (one `{ slotStartedAt, isOnline }` per sync, oldest first; no sync runs from 02:00 to 05:59 UTC). Use it to tell a device that is rarely online from one that is always reachable. For the current online status and last check-in only, use `getDevice` (`mdmStatuses.online`, `lastSeenAt`).","operationId":"getDeviceReachability","parameters":[{"name":"deviceId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetDeviceReachability_Output"}}}}},"summary":"Get device reachability","tags":["Devices"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/devices/code-history":{"post":{"description":"Return the decrypted code history (recovery key, iCloud bypass code, unlock PIN, recovery OS password) for MULTIPLE devices in one call, grouped by device id, each newest first. Provide a list of `deviceIds` (up to 200 per call), optionally filtered by `type`. Devices that do not exist, or that do not belong to your company, are returned with an empty `data` array. Prefer this over calling `getDeviceCodeHistory` once per device.","operationId":"getDevicesCodeHistory","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetDevicesCodeHistoryBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetDevicesCodeHistory_Output"}}}}},"summary":"Get code history for multiple devices","tags":["Devices"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/devices/{deviceId}/custom-fields":{"get":{"description":"Return all Active custom field definitions for ONE device, each paired with the current stored value (or null when unset). For SELECT / MULTI_SELECT fields the `options` catalog is included so you can map option ids to labels. For many devices at once, use `getDevicesCustomFields` instead of calling this endpoint in a loop.","operationId":"getDeviceCustomFields","parameters":[{"name":"deviceId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetDeviceCustomFields_Output"}}}}},"summary":"Get device custom fields","tags":["Devices"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/devices/custom-fields":{"post":{"description":"Return all Active custom field definitions for MULTIPLE devices in one call, each paired with the current stored value (or null when unset), grouped by device id. Provide a list of `deviceIds` (up to 500 per call). Prefer this over calling `getDeviceCustomFields` once per device.","operationId":"getDevicesCustomFields","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetDevicesCustomFieldsBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetDevicesCustomFields_Output"}}}}},"summary":"Get custom fields for multiple devices","tags":["Devices"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/devices/{deviceId}/custom-fields/{customFieldId}":{"put":{"description":"Set or overwrite a custom field value on a device. Idempotent. Returns the updated field (definition + value). For SELECT supply the option id (string); for MULTI_SELECT supply an array of option ids. Option ids can be read from the `getDeviceCustomFields` endpoint.","operationId":"setDeviceCustomFieldValue","parameters":[{"name":"deviceId","required":true,"in":"path","schema":{"type":"string"}},{"name":"customFieldId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetDeviceCustomFieldValueBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeviceCustomFieldItem_Output"}}}}},"summary":"Set a device custom field value","tags":["Devices"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}},"delete":{"description":"Remove the stored value for a custom field on a device. Returns the updated field (value reset to null).","operationId":"clearDeviceCustomFieldValue","parameters":[{"name":"deviceId","required":true,"in":"path","schema":{"type":"string"}},{"name":"customFieldId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeviceCustomFieldItem_Output"}}}}},"summary":"Clear a device custom field value","tags":["Devices"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/devices/search":{"post":{"description":"Return the devices of your company as a paginated JSON list of full device objects — use it to look up, filter or answer questions about the devices themselves. Send an empty body to list everything; add a `filter` to narrow it. Every `filter` entry is keyed by a `key` from `getDeviceFilterCatalog` (`GET /devices/filters-options`) and its value is always a clause `{ \"operationType\": \"INCLUDE\" | \"EXCLUDE\", \"values\": [...] }` — there are no comparison operators (no `eq`, `gt`, `contains`) and never a bare value (illustrative clauses are on the `filter` parameter). An unknown key is rejected with 400 — the criterion is never silently ignored. Add `matchAny: true` for OR instead of AND. `search` is free text over name, serial number, IMEI, owner and custom field values. Device objects are large, so pages are small (max 100), and leave out `imeis`: read them with `getDevice`, or with `exportDevices` for many devices. To count devices, one total or a breakdown of up to 20 filters, use `countDevices` instead. To extract the whole inventory as a CSV file (spreadsheet, download, report), use `exportDevices` instead, or `exportInventory` for a file of devices and the employees holding them, with no device code. Retired devices are left out unless the filter has an `availableStatus` clause: INCLUDE keeps only the statuses it lists, EXCLUDE every other status, retired ones included.","operationId":"getDevices","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchDevicesBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchDevices_Output"}}}}},"summary":"Get devices, optionally narrowed by a filter","tags":["Devices"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/devices/count":{"post":{"description":"Return only numbers: `{\"counts\":{\"<label>\":<number>}}`, one per labelled query. Use it for any how-many question about devices, one total or a breakdown (by MDM status, platform, availability, encryption, online state, custom field…) with one query per bucket, instead of calling `getDevices` once per bucket. A query takes the `filter`, `matchAny` and `search` of `getDevices`, keyed by the `key`s of `getDeviceFilterCatalog`, and counts what `getDevices` would return for it (`pagination.totalElements`): retired devices are left out unless the query has an `availableStatus` clause (INCLUDE keeps only the statuses it lists, EXCLUDE every other status, retired ones included), so the empty query `{}` counts every device not retired. An unknown criterion in any query rejects the whole call with 400, naming the label and the key. To list the devices behind a count, use `getDevices`. For the company headline KPIs (devices in use and in stock, MDM on or off, encryption, online) in one read, use `getCompanyMetrics`.","operationId":"countDevices","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CountDevicesBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CountDevices_Output"}}}}},"summary":"Count devices for up to 20 filters in one call","tags":["Devices"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/devices/custom-fields/batch":{"post":{"description":"Set, overwrite, or clear custom field values across many devices in one call. Provide a list of `items`, each targeting one (deviceId, customFieldId) pair with the `value` to write (null clears it). Each pair must be unique within the batch (duplicates are rejected with 400). Up to 100 items per call. Writes are best-effort and independent: the call returns 200 with a `results` manifest reporting `ok` / `error` per item — always inspect `results` rather than relying on the HTTP status to detect partial failures. For SELECT supply the option id (string); for MULTI_SELECT supply an array of option ids (readable from `getDeviceCustomFields`).","operationId":"setDeviceCustomFieldValuesBatch","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetDeviceCustomFieldValuesBatchBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetDeviceCustomFieldValuesBatchResult_Output"}}}}},"summary":"Set device custom field values in batch","tags":["Devices"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/devices/{deviceId}/software":{"get":{"description":"Return the paginated list of Primo-managed software installed on or targeted for ONE device, each with its install status (installed, in_progress, failed, not_installed), installed/available versions, and the actions available on it (whether install/update can run and why not, whether it can be uninstalled) — check these before calling `installDeviceSoftware`/`uninstallDeviceSoftware`. Also returns whether the device is currently online. For the company-wide catalog of software titles managed by your company (not tied to one device), use `getSoftwares` instead.","operationId":"getDeviceSoftware","parameters":[{"name":"deviceId","required":true,"in":"path","schema":{"type":"string"}},{"name":"page","required":false,"in":"query","description":"Page number","schema":{"type":"number"}},{"name":"perPage","required":false,"in":"query","description":"Number of items per page (max 100)","schema":{"type":"number"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetDeviceSoftware_Output"}}}}},"summary":"List software on a device","tags":["Devices"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/devices/{deviceId}/mdm-controls":{"get":{"description":"Return the complete list of enabled MDM controls that TARGET ONE device — the policies this machine is meant to receive (disk encryption, screen lock, OS restrictions, installed profiles…), each with its id, name, type, platform, tags and how it reaches the device (`targetMethod`). Targeting only: a control listed here is INTENDED for the device, which does NOT mean it is installed on it or that the device complies with it — for that, read `getComplianceAlerts` on the same device, whose alerts carry `mdmControlId`. Disabled controls are never listed, and a device that is not enrolled in MDM still has targeted controls (none of them applied). Not paginated, the list is complete. For the company-wide list of controls, use `getMdmControls`; for one control full configuration and targeting, use `getMdmControl`.","operationId":"getDeviceMdmControls","parameters":[{"name":"deviceId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetDeviceMdmControls_Output"}}}}},"summary":"List the MDM controls that apply to a device","tags":["Devices"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/devices/{deviceId}/software/{softwareId}/install-logs":{"get":{"description":"Return every install attempt of ONE software on ONE device, newest first (up to the 20 most recent): status, script/query output for a package, the decoded MDM error for an App Store app, when it ran, and what triggered it (`manual`, `selfService`, `policy` with its name, or `setupExperience`). MDM retries a failed install, so the OLDEST attempt usually carries the root cause while later ones fail on the debris of the first — read the whole list, not just `attempts[0]`. `skippedInstall` marks an attempt that was postponed because the app was open, not a real failure. To list all software on a device, use `getDeviceSoftware` instead.","operationId":"getSoftwareInstallLogs","parameters":[{"name":"deviceId","required":true,"in":"path","schema":{"type":"string"}},{"name":"softwareId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetSoftwareInstallLogs_Output"}}}}},"summary":"Get software install logs on a device","tags":["Devices"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/devices/{deviceId}/software/{softwareId}/install":{"post":{"description":"Install ONE Primo-managed software on ONE device via MDM. The software must already exist in your company catalog (see `getSoftwares`) and be available for install on that device. To remove it instead, use `uninstallDeviceSoftware`.","operationId":"installDeviceSoftware","parameters":[{"name":"deviceId","required":true,"in":"path","schema":{"type":"string"}},{"name":"softwareId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeviceSoftwareActionResult_Output"}}}}},"summary":"Install a software on a device","tags":["Devices"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/devices/{deviceId}/software/{softwareId}/uninstall":{"post":{"description":"Uninstall ONE Primo-managed software from ONE device via MDM. Not all software supports uninstall. To install it instead, use `installDeviceSoftware`.","operationId":"uninstallDeviceSoftware","parameters":[{"name":"deviceId","required":true,"in":"path","schema":{"type":"string"}},{"name":"softwareId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeviceSoftwareActionResult_Output"}}}}},"summary":"Uninstall a software from a device","tags":["Devices"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/devices/{deviceId}/software/sync":{"post":{"description":"Trigger a resync of ONE device's software from the MDM provider (Fleet) so its install state (installed/failed/in_progress) is refreshed. Runs in the background; re-read with `getDeviceSoftware` afterwards. To resync the whole company catalog instead, use `syncCompanySoftwares`. This reads what the MDM already knows, and only the software rows: to make the device itself re-report its inventory after a fix, use `refetchDevice` first; to refresh the rest of Primo's device record from the MDM, use `syncPrimoDevice`.","operationId":"syncDeviceSoftware","parameters":[{"name":"deviceId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeviceSoftwareActionResult_Output"}}}}},"summary":"Sync a device software state","tags":["Devices"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/devices/{deviceId}/activities":{"get":{"description":"Return the paginated list of past MDM activities for a device, as reported by the MDM layer. The `details` field is a polymorphic passthrough whose shape varies by activity type. For device lifecycle events recorded by Primo (lock, wipe, retire…), use `getDeviceEvents` instead.","operationId":"getDeviceActivities","parameters":[{"name":"deviceId","required":true,"in":"path","schema":{"type":"string"}},{"name":"orderDirection","required":false,"in":"query","description":"Order direction","schema":{"enum":["asc","desc"],"type":"string"}},{"name":"orderKey","required":false,"in":"query","description":"Field to order results by","schema":{"enum":["id","created_at","activity_type"],"type":"string"}},{"name":"page","required":false,"in":"query","description":"Page number","schema":{"type":"number"}},{"name":"perPage","required":false,"in":"query","description":"Number of items per page (max 100)","schema":{"type":"number"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetDeviceActivities_Output"}}}}},"summary":"List past activities for a device","tags":["Devices"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/devices/{deviceId}/activities/upcoming":{"get":{"description":"Return the paginated list of upcoming (queued) MDM activities for a device. The `details` field is a polymorphic passthrough whose shape varies by activity type. To clear one wedged item out of that queue (a stuck install blocking everything behind it), use `cancelDeviceUpcomingActivity` with the `uuid` returned here.","operationId":"getDeviceUpcomingActivities","parameters":[{"name":"deviceId","required":true,"in":"path","schema":{"type":"string"}},{"name":"page","required":false,"in":"query","description":"Page number","schema":{"type":"number"}},{"name":"perPage","required":false,"in":"query","description":"Number of items per page (max 100)","schema":{"type":"number"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetDeviceUpcomingActivities_Output"}}}}},"summary":"List upcoming activities for a device","tags":["Devices"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/devices/{deviceId}/activities/upcoming/{activityUuid}":{"delete":{"description":"Cancel ONE activity still queued on a device — a pending software install or uninstall, or a queued script — identified by the `uuid` returned by `getDeviceUpcomingActivities`. Use this to clear an install that is wedged (a package install Fleet leaves `in_progress` for up to an hour after the device went offline) and unblock the activities queued behind it. This does not undo work already done on the device: an activity that already started or finished cannot be cancelled and returns a 404. Cancelling is visible to the person waiting on that install, so confirm with the user before calling it. The software row keeps its `in_progress` state until the device state is resynced, so call `syncDeviceSoftware` afterwards before re-reading `getDeviceSoftware`. To queue the install again, use `installDeviceSoftware`.","operationId":"cancelDeviceUpcomingActivity","parameters":[{"name":"deviceId","required":true,"in":"path","schema":{"type":"string"}},{"name":"activityUuid","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeviceActionResult_Output"}}}}},"summary":"Cancel a queued activity on a device","tags":["Devices"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/devices/{deviceId}/mdm-controls/{mdmControlId}/resend-profile":{"post":{"description":"Ask the MDM to deliver an MDM control's configuration profile to ONE device again — the remediation for a profile the device failed to apply, without re-applying the control to every device it targets. Take `mdmControlId` from the compliance alert, and call `getComplianceAlertDetails` first: it reports `enforcement.profile.resendable`, which is `true` only when this call would be accepted. A resend is refused when the profile is already being delivered (`pending` / `verifying` — wait for the device to check in), and when the control is enforced by a declaration instead of a profile (OS update on Apple, USB blocking on macOS, and the Android controls — those have no per-device redelivery at all). Delivery is asynchronous and needs the device to check in, so it is NOT done when this returns: re-read `getComplianceAlertDetails` with the same alert id later. Only the profile is resent — to re-run a control's script use `runDeviceScript`, to reinstall its software `installDeviceSoftware`, to re-run its enforcers `syncPrimoDevice`.","operationId":"resendDeviceProfile","parameters":[{"name":"deviceId","required":true,"in":"path","schema":{"type":"string"}},{"name":"mdmControlId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"202":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResendDeviceProfileResult_Output"}}}}},"summary":"Resend one MDM control's configuration profile to one device","tags":["Devices"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/devices/{deviceId}/sync":{"post":{"description":"Pull ONE device's current state from the MDM into Primo — hardware and OS details, disk encryption, users, compliance and MDM/EDR status — and refresh the labels and assignment suggestions that depend on them. This is the Primo side of a device refresh: `refetchDevice` asks the device to re-report to the MDM, this brings what the MDM holds into Primo, so after a fix the two together make `getDevice` answer with reality. Prefer this after any change made outside Primo; to refresh only the Primo-managed software rows, use `syncDeviceSoftware`. EXPENSIVE — do not call it in a loop or across a fleet: one call runs a full MDM sync and queues label, device-user and assignment-suggestion jobs behind it. Call it once for the device you just changed, then re-read `getDevice`. Set `forceEnforcerExecution` to also re-run the MDM control enforcers and re-fetch the disk encryption key — slower still, and it can queue commands on the device.","operationId":"syncPrimoDevice","parameters":[{"name":"deviceId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeviceActionResult_Output"}}}}},"summary":"Refresh Primo's record of a device from the MDM","tags":["Devices"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/devices/{deviceId}/refetch":{"post":{"description":"Ask ONE device to re-report its details, software inventory and policy results to the MDM. This refreshes what the MDM knows about the device, NOT Primo's own device record: the MDM only flags the device, the report lands the next time it checks in, and Primo picks that state up later through its own device sync. Use it after a fix (a script run, an install) before re-reading `getDeviceSoftware`, which otherwise still answers with the state captured by the last inventory cycle. Safe to call repeatedly. To re-read the Primo-managed software rows from the MDM instead of asking the device, use `syncDeviceSoftware`; to pull what the MDM already knows into Primo's own device record, use `syncPrimoDevice`.","operationId":"refetchDevice","parameters":[{"name":"deviceId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeviceActionResult_Output"}}}}},"summary":"Ask a device to report its state back to the MDM","tags":["Devices"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/devices/{deviceId}/commands":{"get":{"description":"Return the paginated list of raw MDM protocol commands sent to a device, including their status (ran, pending, failed). Use `getDeviceCommandResults` for the execution results of one command. For a higher-level history, use `getDeviceActivities` (MDM activity feed) or `getDeviceEvents` (Primo lifecycle events).","operationId":"getDeviceCommands","parameters":[{"name":"deviceId","required":true,"in":"path","schema":{"type":"string"}},{"name":"commandStatus","required":false,"in":"query","description":"Filter by command status","schema":{"enum":["ran","pending","failed"],"type":"string"}},{"name":"requestType","required":false,"in":"query","description":"Filter by MDM command request type","schema":{"type":"string"}},{"name":"orderDirection","required":false,"in":"query","description":"Order direction","schema":{"enum":["asc","desc"],"type":"string"}},{"name":"orderKey","required":false,"in":"query","description":"Field to order results by","schema":{"enum":["host_uuid","command_uuid","status","updated_at","request_type","hostname","name"],"type":"string"}},{"name":"page","required":false,"in":"query","description":"Page number","schema":{"type":"number"}},{"name":"perPage","required":false,"in":"query","description":"Number of items per page (max 100)","schema":{"type":"number"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetDeviceCommands_Output"}}}}},"summary":"List MDM commands for a device","tags":["Devices"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/devices/{deviceId}/commands/{commandUuid}/results":{"get":{"description":"Return the execution results for a specific MDM command on a device.","operationId":"getDeviceCommandResults","parameters":[{"name":"deviceId","required":true,"in":"path","schema":{"type":"string"}},{"name":"commandUuid","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetDeviceCommandResults_Output"}}}}},"summary":"Get results for an MDM command","tags":["Devices"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/scripts":{"get":{"description":"Return your company's saved scripts as JSON — id, name, and the platforms each one can run on. Use this to discover a `scriptId` before calling `runScript` or `runDeviceScript`.\n\nA script's platforms come from its file extension: `.sh` (macOS + Linux), `.py` (macOS + Linux), `.ps1` (Windows).\n\nTo read a script's source, use `getScript`. To see what has actually been run, use `getScriptRuns` instead.","operationId":"getScripts","parameters":[],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetScripts_Output"}}}}},"summary":"List the saved scripts","tags":["Scripts"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/script-runs":{"get":{"description":"Return the paginated history of script runs, newest first — what was run, on which target, by whom, and how many devices are in each execution status. Use this to answer \"what scripts have been run recently?\".\n\nFor the per-device outcomes of one run, use `getScriptRunExecutions`. For everything that ran on one device, use `getDeviceScriptExecutions`. To list the scripts available to run rather than past runs, use `getScripts`.\n\nExecutions are reconciled with FleetDM by a background sweep that runs every 15 minutes, so a freshly created run reads back as `pending` until the next sweep. Poll no more often than that.","operationId":"getScriptRuns","parameters":[{"name":"page","required":false,"in":"query","description":"Page number","schema":{"minimum":1,"maximum":9007199254740991,"default":1,"type":"number"}},{"name":"perPage","required":false,"in":"query","description":"Number of items per page (max 100)","schema":{"minimum":1,"maximum":100,"default":50,"type":"number"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetScriptRuns_Output"}}}}},"summary":"List script runs","tags":["Scripts"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}},"post":{"description":"Run a script on all devices, on one or more device groups, or on an explicit list of devices — intersected with the given platforms. Pass `{ \"scriptId\": 12 }` to run a saved script (see `getScripts`), or `{ \"contents\": \"...\" }` to send the source inline. An inline run may only target a single device.\n\nThe target is resolved once, at trigger time: devices that join a group later are not included. The response returns immediately with every execution `pending`; poll `getScriptRun` for progress.\n\nTo run on exactly one device, `runDeviceScript` is the shorter equivalent. To check how many devices would be reached without executing anything, use `previewScriptRunTarget`.\n\n⚠️ **This executes arbitrary code on the targeted devices with elevated privileges, and is not idempotent** — repeating the call runs the script again. Review the script and the target before calling.\n\n**Supported platforms:** macOS, Windows, Linux. Not supported: iOS, Android, ChromeOS.\n\nExecutions are reconciled with FleetDM by a background sweep that runs every 15 minutes, so a freshly created run reads back as `pending` until the next sweep. Poll no more often than that.","operationId":"runScript","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunScriptBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunScript_Output"}}}}},"summary":"Run a script on a target","tags":["Scripts"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/script-runs/preview-target-count":{"post":{"description":"Return how many devices a run with this target and these platforms would resolve to, using exactly the same resolution as `runScript`. Nothing is executed. Call this before `runScript` to check the blast radius, especially with `target.type = \"all\"`.","operationId":"previewScriptRunTarget","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreviewScriptRunTargetBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreviewScriptRunTarget_Output"}}}}},"summary":"Count the devices a script run would reach","tags":["Scripts"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/script-runs/{runId}/executions":{"get":{"description":"Return the paginated executions of one script run — one per targeted device, each with its status, output, exit code and runtime. Use this to see which devices succeeded and read the script output.\n\nFor the run's summary counts, use `getScriptRun`. For everything that ran on one device across all runs, use `getDeviceScriptExecutions`.\n\nExecutions are reconciled with FleetDM by a background sweep that runs every 15 minutes, so a freshly created run reads back as `pending` until the next sweep. Poll no more often than that.","operationId":"getScriptRunExecutions","parameters":[{"name":"runId","required":true,"in":"path","schema":{"type":"string"}},{"name":"page","required":false,"in":"query","description":"Page number","schema":{"minimum":1,"maximum":9007199254740991,"default":1,"type":"number"}},{"name":"perPage","required":false,"in":"query","description":"Number of items per page (max 100)","schema":{"minimum":1,"maximum":100,"default":50,"type":"number"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetScriptRunExecutions_Output"}}}}},"summary":"List the per-device results of a script run","tags":["Scripts"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/script-runs/{runId}":{"get":{"description":"Return one script run: the script as executed (including its source), the resolved target, and the count of executions in each status. This is the endpoint to poll after `runScript` to follow progress.\n\nFor the per-device outcomes, use `getScriptRunExecutions`.\n\nExecutions are reconciled with FleetDM by a background sweep that runs every 15 minutes, so a freshly created run reads back as `pending` until the next sweep. Poll no more often than that.","operationId":"getScriptRun","parameters":[{"name":"runId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetScriptRun_Output"}}}}},"summary":"Get a script run","tags":["Scripts"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/scripts/{scriptId}":{"get":{"description":"Return one saved script with its full source. Use this to review what a script does before running it. To list the available scripts, use `getScripts`.","operationId":"getScript","parameters":[{"name":"scriptId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetScript_Output"}}}}},"summary":"Get a saved script and its source","tags":["Scripts"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/mdm-controls":{"get":{"description":"Return the list of MDM controls configured for your company — the device policies deployed to your fleet (disk encryption, screen lock, OS restrictions, installed profiles…) — with id, name, type, platform, tags, enabled, and target method. Use `getMdmControl` for one control's full configuration and targeting, and `getMdmControlCatalog` to discover which control types can be created.","operationId":"getMdmControls","parameters":[{"name":"page","required":false,"in":"query","description":"Page number","schema":{"minimum":1,"maximum":9007199254740991,"default":1,"type":"number"}},{"name":"perPage","required":false,"in":"query","description":"Number of items per page (max 100)","schema":{"minimum":1,"maximum":100,"default":50,"type":"number"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetMdmControls_Output"}}}}},"summary":"Get all MDM controls","tags":["MdmControls"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}},"post":{"description":"Create a new MDM control of the given `type` with its `configurationPayload` and targeting. Discover creatable types and their config JSON Schema via GET /mdm-controls/catalog. `name` is optional — when omitted, the catalog default name for the type is used; supply a name to create several controls of one type (some profile-backed types require unique names). `enabled` defaults to true, so a created control is deployed to its targeted devices immediately. `configurationPayload` must match the type's config schema (send null for config-less types). Targeting is set via `targetMethod`: \"All\" (every device) or \"DeviceGroup\" (`includedDeviceGroupIds`/`excludedDeviceGroupIds`). Returns the created control `id`. Invalid config/targeting returns 400, an unknown device group 404, a name/profile conflict 409, MDM not configured for the company 412, and demo companies are not allowed to create MDM controls (403).","operationId":"createMdmControl","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMdmControlBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMdmControl_Output"}}}}},"summary":"Create an MDM control","tags":["MdmControls"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/mdm-controls/catalog":{"get":{"description":"Return the catalog of all creatable MDM control types with their name, description, platform, category, activation status, and JSON Schema for the configuration payload. Intended for AI/MCP agents to discover which control types exist and how to configure them.","operationId":"getMdmControlCatalog","parameters":[],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetMdmControlCatalog_Output"}}}}},"summary":"Get the MDM control type catalog","tags":["MdmControls"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/mdm-controls/{mdmControlId}":{"get":{"description":"Return MDM control details for the given control ID, including target details and configuration payload.","operationId":"getMdmControl","parameters":[{"name":"mdmControlId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"Get an MDM control by ID","tags":["MdmControls"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}},"patch":{"description":"Partially update an existing MDM control by ID. Send only the fields you want to change — any omitted field is left unchanged. `type` is required and must match the control (it selects the config schema). Editable fields: `name`, `enabled`, `configurationPayload`, and targeting. `configurationPayload` fully replaces the stored config when present (not merged); omit it to keep the current config, or send null to clear it. Targeting is set via `targetMethod` (omit to keep current): \"All\" (every device) or \"DeviceGroup\" (`includedDeviceGroupIds`/`excludedDeviceGroupIds`). An unknown ID returns 404, invalid config/targeting 400, a name/profile conflict 409, and demo companies are not allowed to update MDM controls (403).","operationId":"updateMdmControl","parameters":[{"name":"mdmControlId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateMdmControlBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateMdmControl_Output"}}}}},"summary":"Update an MDM control","tags":["MdmControls"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}},"delete":{"description":"Delete an MDM control by ID. Removing the control undeploys it from every targeted device. An unknown ID returns 404. Demo companies are not allowed to delete MDM controls (403).","operationId":"deleteMdmControl","parameters":[{"name":"mdmControlId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteMdmControl_Output"}}}}},"summary":"Delete an MDM control","tags":["MdmControls"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/mdm-controls/{mdmControlId}/tags":{"put":{"description":"Replace the full set of tags on an MDM control. Send the complete desired tag list — any existing tag not included is removed. An unknown control ID returns 404.","operationId":"updateMdmControlTags","parameters":[{"name":"mdmControlId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateMdmControlTagsBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateMdmControlTags_Output"}}}}},"summary":"Update an MDM control's tags","tags":["MdmControls"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/device-groups":{"get":{"description":"Return the list of device groups for your company (id, name).","operationId":"getDeviceGroups","parameters":[{"name":"page","required":false,"in":"query","description":"Page number","schema":{"minimum":1,"maximum":9007199254740991,"default":1,"type":"number"}},{"name":"perPage","required":false,"in":"query","description":"Number of items per page (max 100)","schema":{"minimum":1,"maximum":100,"default":50,"type":"number"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetDeviceGroups_Output"}}}}},"summary":"Get all device groups","tags":["DeviceGroups"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}},"post":{"description":"Create a device group with a `name` and a `target` filter. `name` must be unique per company — a conflicting name is rejected with 409; `getDeviceGroups` (`GET /device-groups`) lists the existing names. Build the `target` from `getDeviceGroupFiltersOptions` (`GET /device-groups/filters-options`); `validateDeviceGroupTarget` (`POST /device-groups/validate-target`) reports whether it is targetable and how many devices it matches, without creating anything. An invalid `target` is rejected with 400.","operationId":"createDeviceGroup","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeviceGroupInput"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeviceGroup_Output"}}}}},"summary":"Create a device group","tags":["DeviceGroups"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/device-groups/{deviceGroupId}/relations":{"get":{"description":"List the softwares and MDM controls that target this device group. A group can only be deleted once both lists are empty — call this before DELETE to discover (and then remove) what still references it, or to explain a 409.","operationId":"getDeviceGroupRelations","parameters":[{"name":"deviceGroupId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetDeviceGroupRelations_Output"}}}}},"summary":"Get what uses a device group","tags":["DeviceGroups"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/device-groups/filters-options":{"get":{"description":"Return every criterion (native device attributes plus custom fields) that may target a device group, with its live company values inline. Use this to build a valid device-group target. This is a deliberately narrower set than the device **search** catalog (`getDeviceFilterCatalog`): a group targeting a volatile criterion would change population daily, and every MDM control targeting that group with it. To search the inventory instead of targeting a group, use `getDeviceFilterCatalog` + `getDevices`.","operationId":"getDeviceGroupFiltersOptions","parameters":[],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetDeviceGroupFiltersOptions_Output"}}}}},"summary":"Get the device group filter catalog","tags":["DeviceGroups"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/device-groups/{deviceGroupId}":{"put":{"description":"Replace a device group's `name` and `target` filter. Both fields are required — send the full desired state, not a partial patch. `name` must be unique per company (a conflicting name is rejected with 409). Build the `target` from the `GET /device-groups/filters-options` catalog and check it with `validateDeviceGroupTarget` (`POST /device-groups/validate-target`) before updating; an invalid `target` is rejected with 400.","operationId":"updateDeviceGroup","parameters":[{"name":"deviceGroupId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateDeviceGroupInput"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateDeviceGroup_Output"}}}}},"summary":"Update a device group","tags":["DeviceGroups"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}},"delete":{"description":"Delete a device group by ID. A group that is still targeted by an MDM control or a software is rejected with 409 — call `GET /device-groups/:deviceGroupId/relations` to see what references it and remove those first. An unknown ID returns 404; deleting an already-deleted group is a no-op that still returns success.","operationId":"deleteDeviceGroup","parameters":[{"name":"deviceGroupId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteDeviceGroup_Output"}}}}},"summary":"Delete a device group","tags":["DeviceGroups"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}},"get":{"description":"Return the device group: its `target` filter (the same shape create/update accept) plus the device IDs that filter currently resolves to. Read the `target` here before a PUT to change one field while preserving the rest of the targeting.","operationId":"getDeviceGroup","parameters":[{"name":"deviceGroupId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetDeviceGroup_Output"}}}}},"summary":"Get a device group by ID","tags":["DeviceGroups"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/device-groups/validate-target":{"post":{"description":"Validate a device group `target` without persisting anything: it reports whether the target is well-formed, whether every criterion is device-group-targetable (build it from `getDeviceGroupFiltersOptions`), and how many devices it currently matches — so a target that is valid but matches nothing is caught before the group exists. It returns counts and reasons, never device objects: to see WHICH devices match a filter, use `getDevices`.","operationId":"validateDeviceGroupTarget","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidateDeviceGroupTargetInput"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidateDeviceGroupTarget_Output"}}}}},"summary":"Check a device group target before creating the group","tags":["DeviceGroups"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/employees":{"get":{"description":"Return your company's employees as a paginated list. Pass `search` to turn a name or an email into the employee it refers to instead of paging: free text over first and last name, full name in either order, work email and personal email, ignoring case and accents, plus text and URL custom field values. Exactly one result is that person; several mean the name is ambiguous and nobody was found — ask which is meant, never take the first. `id` is the employee itself; `managerId`, `deviceIds` and `accessoryIds` name other records, never a search result. Items carry `id`, `firstName`, `lastName`, `email`, `teams` and `jobs` (`{ id, name }` — teams and job titles), `groups`, `workLocation`, `legalEntity`, `managerId`, `startDate`, `terminationDate`, `onboardingStatus`, `offboardingStatus`, `deviceIds`, `accessoryIds`, `createdAt`, `updatedAt`, plus the MDM enrollment chase fields below. It omits personal data such as the postal address and the personal email — `getEmployee` with an id returns the full record. Never conclude a field is empty from this list alone. A built-in job re-sends an MDM enrollment reminder every 7 days, and each send resets that clock, so an employee the job is still chasing always has a recent `lastEnrollmentRequestSentAt`. `enrollmentReminderStatus` says where each employee stands: `NEVER_SENT` — no enrollment request was ever emailed; `REMINDER_CYCLE_ACTIVE` — a request went out recently and the job will send the next reminder on schedule; `REMINDER_CYCLE_STALLED` — a request went out long enough ago that the job should have reminded them and did not, so nothing further will be sent automatically; `REMINDERS_DISABLED` — reminders are off for this employee, so the job will never contact them. `lastEnrollmentRequestSentAt` and `enrollmentReminderEnabled` are the raw values behind it.","operationId":"getEmployees","parameters":[{"name":"page","required":false,"in":"query","description":"Page number","schema":{"minimum":1,"maximum":9007199254740991,"default":1,"type":"number"}},{"name":"perPage","required":false,"in":"query","description":"Number of items per page (max 100)","schema":{"minimum":1,"maximum":100,"default":50,"type":"number"}},{"name":"search","required":false,"in":"query","description":"Free-text search over first name, last name, full name in either order, work email and personal email, ignoring case and accents. Text and URL custom field values are also matched, case-insensitively and without accent folding.","schema":{"minLength":1,"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetEmployees_Output"}}}}},"summary":"Get employees, optionally narrowed by a search","tags":["Employees"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}},"post":{"description":"Create a new employee in your company. This only creates the record: it never starts an onboarding. To onboard the joiner (ticket, email, SaaS provisioning and equipment steps), call `createOnboarding` with the returned employee id.","operationId":"createEmployee","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEmployeeBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetEmployee_Output"}}}}},"summary":"Create an employee","tags":["Employees"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/employees/{employeeId}":{"get":{"description":"Return the full details for one employee, including their personal address — use it as the HOME shipping address when ordering equipment for a remote employee. For office addresses, use `getCompanyAddresses` instead. It carries the same fields as `getEmployees` — `teams`, `jobs` and the MDM enrollment chase fields (`enrollmentReminderStatus`, `lastEnrollmentRequestSentAt`, `enrollmentReminderEnabled`, documented on `getEmployees`) included — plus `personalEmail`, `address`, `employmentType` and `isRemote`.","operationId":"getEmployee","parameters":[{"name":"employeeId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetEmployee_Output"}}}}},"summary":"Get an employee by ID","tags":["Employees"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}},"patch":{"description":"Update an employee: name, work and personal emails, phone, gender, picture, manager, employment type, job title, teams, work location, legal entity, home address, start date and termination date. Only the provided fields are changed; omitted fields are left untouched.\n\n`teams` replaces the full set of teams. `job`, `workLocation`, `legalEntity` and `teams` accept either an existing reference `id` or a `name` — a new reference is created when the name does not match an existing one.\n\nFor an employee synchronised from a connected HRIS, the fields that HRIS keeps in sync cannot be changed here: the request is refused with `FIELDS_MANAGED_BY_HRIS` and the list of refused `fields`, and nothing is written — change them in the HRIS. `employmentType` is never synced.\n\n`terminationDate` sets the last day only. It starts no offboarding, and no operation of this API starts one: an admin starts it from the employee in the Primo cockpit, and an employee synchronised from an HRIS gets it from the sync. When an offboarding is already open, its termination date follows; clearing the date while it is open is refused with `OFFBOARDING_OPEN`.","operationId":"updateEmployee","parameters":[{"name":"employeeId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateEmployeeBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetEmployee_Output"}}}}},"summary":"Update an employee","tags":["Employees"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/employees/{employeeId}/custom-fields":{"get":{"description":"Return all Active custom field definitions for the employee, each paired with the current stored value (or null when unset). For SELECT / MULTI_SELECT fields the `options` catalog is included so you can map option ids to labels.","operationId":"getEmployeeCustomFields","parameters":[{"name":"employeeId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetEmployeeCustomFields_Output"}}}}},"summary":"Get employee custom fields","tags":["Employees"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/employees/{employeeId}/hide":{"post":{"description":"Hide an employee from the company directory. Their onboarding and offboarding records are removed.","operationId":"hideEmployee","parameters":[{"name":"employeeId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HideEmployee_Output"}}}}},"summary":"Hide an employee","tags":["Employees"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/employees/{employeeId}/custom-fields/{customFieldId}":{"put":{"description":"Set or overwrite a custom field value on an employee. Idempotent. Returns the updated field (definition + value). For SELECT supply the option id (string); for MULTI_SELECT supply an array of option ids. Option ids can be read from the `getEmployeeCustomFields` endpoint.","operationId":"setEmployeeCustomFieldValue","parameters":[{"name":"employeeId","required":true,"in":"path","schema":{"type":"string"}},{"name":"customFieldId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetEmployeeCustomFieldValueBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmployeeCustomFieldItem_Output"}}}}},"summary":"Set an employee custom field value","tags":["Employees"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}},"delete":{"description":"Remove the stored value for a custom field on an employee. Returns the updated field (value reset to null).","operationId":"clearEmployeeCustomFieldValue","parameters":[{"name":"employeeId","required":true,"in":"path","schema":{"type":"string"}},{"name":"customFieldId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmployeeCustomFieldItem_Output"}}}}},"summary":"Clear an employee custom field value","tags":["Employees"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/employees/{employeeId}/unhide":{"post":{"description":"Make a previously hidden employee visible again in the company directory.","operationId":"unhideEmployee","parameters":[{"name":"employeeId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HideEmployee_Output"}}}}},"summary":"Unhide an employee","tags":["Employees"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/employees/{employeeId}/send-enrollment-request":{"post":{"description":"Trigger the Primo-branded MDM enrollment invitation for the employee. It is sent to the employee's communication address.","operationId":"sendEnrollmentRequest","parameters":[{"name":"employeeId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendEnrollmentRequest_Output"}}}}},"summary":"Send an MDM enrollment request to an employee","tags":["Employees"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/equipment-policy":{"get":{"description":"Return the company equipment policy: the editable draft text, the published text (what the agent sees at runtime, or null if never published), and the publication status. Read this before updating so you can re-send the full, edited body and diff draft against published.","operationId":"getEquipmentPolicy","parameters":[],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetEquipmentPolicyResponseDto_Output"}}}}},"summary":"Get the equipment policy","tags":["EquipmentPolicy"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/equipment-policy/result":{"get":{"description":"Return the computed equipment policy result: the recommended device and accessory product IDs per country, each country compute status (computing / ready / failed), and whether a policy is set up. The compute is asynchronous and fanned out per country, so a country can be `computing` while others are `ready`. `isSetup` is false when no policy has been configured.","operationId":"getEquipmentPolicyResult","parameters":[],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetEquipmentPolicyResultResponseDto_Output"}}}}},"summary":"Get the computed equipment policy result","tags":["EquipmentPolicy"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/purchasing-policy":{"get":{"description":"Return the company purchasing policy: the editable draft text, the published text (what the agent sees at runtime, or null if never published), and the publication status. Read this before updating so you can re-send the full, edited body and diff draft against published.","operationId":"getPurchasingPolicy","parameters":[],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetPurchasingPolicyResponseDto_Output"}}}}},"summary":"Get the purchasing policy","tags":["PurchasingPolicy"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/accessories":{"get":{"description":"Return the list of accessories for your company. Pass `unassigned: true` to see only what is in stock — nobody owns it, so it can be handed out — and `type` to keep only one kind of accessory, so a request for a spare keyboard does not page through the whole inventory. The two combine: `unassigned: true` with `type: \"KEYBOARD\"` answers \"is there a keyboard available?\" in one call, and `pagination.totalElements` is how many there are. `unassigned: false` returns only accessories someone already holds. An accessory can have custom fields (see `getAccessoryCustomFields`).","operationId":"getAccessories","parameters":[{"name":"page","required":false,"in":"query","description":"Page number","schema":{"minimum":1,"maximum":9007199254740991,"default":1,"type":"number"}},{"name":"perPage","required":false,"in":"query","description":"Number of items per page (max 100)","schema":{"minimum":1,"maximum":100,"default":50,"type":"number"}},{"name":"unassigned","required":false,"in":"query","description":"Narrow to stock: true returns only accessories with no owner, false only those currently assigned. Omit to return both.","schema":{"type":"boolean"}},{"name":"type","required":false,"in":"query","description":"Return only accessories of this type.","schema":{"enum":["MONITOR","KEYBOARD","MOUSE","MOUSEPAD","WEBCAM","HEADSET","SPEAKER","CABLE_ADAPTER","HUB","CHARGER","STORAGE_DEVICE","LAPTOP_CASE","ERGONOMIC","SHIPPING_MATERIAL","FIDO_KEY","ACCESS_CARD","NETWORK_DEVICE","FIREWALL","ROUTER","SWITCH","OTHER"],"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetAccessories_Output"}}}}},"summary":"Get accessories, optionally narrowed to stock and to one type","tags":["Accessories"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}},"post":{"description":"Create an accessory for your company.","operationId":"createAccessory","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAccessoryBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetAccessory_Output"}}}}},"summary":"Create an accessory","tags":["Accessories"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/accessories/{accessoryId}":{"get":{"description":"Return the accessory details for the given accessory ID.","operationId":"getAccessory","parameters":[{"name":"accessoryId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetAccessory_Output"}}}}},"summary":"Get an accessory by ID","tags":["Accessories"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}},"put":{"description":"Update an existing accessory for your company.","operationId":"updateAccessory","parameters":[{"name":"accessoryId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateAccessoryBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetAccessory_Output"}}}}},"summary":"Update an accessory","tags":["Accessories"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/accessories/{accessoryId}/custom-fields":{"get":{"description":"Return all Active custom field definitions for the accessory, each paired with the current stored value (or null when unset). For SELECT / MULTI_SELECT fields the `options` catalog is included so you can map option ids to labels.","operationId":"getAccessoryCustomFields","parameters":[{"name":"accessoryId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetAccessoryCustomFields_Output"}}}}},"summary":"Get accessory custom fields","tags":["Accessories"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/accessories/{accessoryId}/custom-fields/{customFieldId}":{"put":{"description":"Set or overwrite a custom field value on an accessory. Idempotent. Returns the updated field (definition + value). For SELECT supply the option id (string); for MULTI_SELECT supply an array of option ids. Option ids can be read from the `getAccessoryCustomFields` endpoint.","operationId":"setAccessoryCustomFieldValue","parameters":[{"name":"accessoryId","required":true,"in":"path","schema":{"type":"string"}},{"name":"customFieldId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetAccessoryCustomFieldValueBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccessoryCustomFieldItem_Output"}}}}},"summary":"Set an accessory custom field value","tags":["Accessories"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}},"delete":{"description":"Remove the stored value for a custom field on an accessory. Returns the updated field (value reset to null).","operationId":"clearAccessoryCustomFieldValue","parameters":[{"name":"accessoryId","required":true,"in":"path","schema":{"type":"string"}},{"name":"customFieldId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccessoryCustomFieldItem_Output"}}}}},"summary":"Clear an accessory custom field value","tags":["Accessories"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/accessories/{accessoryId}/assign":{"post":{"description":"Assign an accessory to an employee. Pass ownerId as null to unassign the current owner.","operationId":"assignAccessory","parameters":[{"name":"accessoryId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssignAccessoryBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccessoryActionSuccess_Output"}}}}},"summary":"Assign an accessory to an employee","tags":["Accessories"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/accessories/{accessoryId}/archive":{"post":{"description":"Archive (soft-delete) an accessory. The accessory is unassigned from its current owner and marked as deleted.","operationId":"archiveAccessory","parameters":[{"name":"accessoryId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccessoryActionSuccess_Output"}}}}},"summary":"Archive an accessory","tags":["Accessories"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/compliance/alerts":{"get":{"description":"Return the paginated list of active compliance alerts — one per (device, compliance rule) pair currently in a non-compliant status (e.g. not enrolled, offline, disk not encrypted). Each alert carries its device (`deviceId`, `deviceName`, `devicePlatform`, `owner`), its rule (`complianceRuleId`, `ruleType`) and, for control-based rules, the `mdmControlId`. Optionally filter by a single device ID — to narrow by platform, owner, status, rule type or last check date, use `searchComplianceAlerts` instead. For the remediation context of the alerts, pass their ids to `getComplianceAlertsDetails` (up to 25 per call). Which statuses trigger an alert is configured per rule — see `getComplianceAlertRules`.","operationId":"getComplianceAlerts","parameters":[{"name":"page","required":false,"in":"query","description":"Page number","schema":{"minimum":1,"maximum":9007199254740991,"default":1,"type":"number"}},{"name":"perPage","required":false,"in":"query","description":"Number of items per page (max 100)","schema":{"minimum":1,"maximum":100,"default":50,"type":"number"}},{"name":"deviceId","required":false,"in":"query","description":"Filter alerts by device ID","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetComplianceAlerts_Output"}}}}},"summary":"Get all active compliance alerts","tags":["Compliance"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/compliance/alerts/search":{"post":{"description":"Return the paginated list of active compliance alerts, narrowed by a `filter` — use it to answer any targeted question about non-compliance (\"which macOS devices are not encrypted\", \"who owns the offline devices\"). Send an empty body to list everything. Every `filter` entry is keyed by a `key` from `getComplianceAlertsFilterCatalog` (`GET /compliance/alerts/filters-options`) and its value is always a clause `{ \"operationType\": \"INCLUDE\" | \"EXCLUDE\", \"values\": [...] }` — never a bare value, never an operator like `eq`. Criteria are ANDed. Example: non-encrypted macOS devices → `{\"filter\":{\"platform\":{\"operationType\":\"INCLUDE\",\"values\":[\"MACOS\"]},\"status\":{\"operationType\":\"INCLUDE\",\"values\":[\"NOT_ENCRYPTED\"]}}}`. An unknown key is rejected with 400 — the criterion is never silently ignored. Each alert already carries its device name, platform and owner, so no per-row `getDevice` chaining is needed. `ownerId` values are employee ids — resolve them with `getEmployees`. For the remediation context of the alerts found, pass their ids to `getComplianceAlertsDetails` (up to 25 per call).","operationId":"searchComplianceAlerts","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchComplianceAlertsBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetComplianceAlerts_Output"}}}}},"summary":"Get compliance alerts, optionally narrowed by a filter","tags":["Compliance"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/compliance/alerts/{alertId}/details":{"get":{"description":"Return everything needed to diagnose and remediate one compliance alert (from `getComplianceAlerts`): the alert, the MDM control behind it with its configuration in clear, the device on both sides (`device.fleet` for the live MDM state — enrollment, last check-in, delivered profiles, failing checks; `device.primo` for what Primo tracks itself — naming, Malwarebytes, SentinelOne, encryption, local admin accounts), and `enforcement`, holding one key per artifact the control carries — a control can carry several. Other mcp tools at your disposal, per key: `profile` → `resendDeviceProfile` (only if `profile.resendable`); `script` → `runDeviceScript` with its `scriptId`; `software` → `installDeviceSoftware` with its `install.softwareId` (never `appId`, the MDM application id); `command` → `syncPrimoDevice` with `forceEnforcerExecution`. No key at all means the enforcement happens outside MDM — the evidence is in `device.primo`, and there is nothing to re-push. Remediation is asynchronous: re-read this same alert id once the device has checked in. A 404 means the check no longer applies to the device, not that the id expired, and is final. To read several alerts, use `getComplianceAlertsDetails` instead of one call per alert. For the full MDM command history, use `getDeviceCommands`.","operationId":"getComplianceAlertDetails","parameters":[{"name":"alertId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetComplianceAlertDetails_Output"}}}}},"summary":"Get the full remediation context of one compliance alert","tags":["Compliance"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/compliance/alerts/details":{"post":{"description":"Return, for MULTIPLE compliance alerts in one call, the same payload as `getComplianceAlertDetails` — the alert, its MDM control with the configuration in clear, the device on both sides and the `enforcement` facets — as `items`, in the order of `alertIds` (up to 25 per call, from `getComplianceAlerts` or `searchComplianceAlerts`). Prefer this over calling `getComplianceAlertDetails` once per alert. An id that matches no alert of your company is listed in `notFoundAlertIds` instead of failing the call: the check no longer applies to that device, and asking again returns the same answer. Each alert weighs 3 to 8 KB, more when its control carries a large profile or script.","operationId":"getComplianceAlertsDetails","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetComplianceAlertsDetailsBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetComplianceAlertsDetails_Output"}}}}},"summary":"Get the full remediation context of several compliance alerts","tags":["Compliance"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/compliance/tickets/{ticketId}/alert/details":{"get":{"description":"Start here when working a compliance ticket: it answers what this ticket is about. Return the same payload as `getComplianceAlertDetails` — the alert, its MDM control with the configuration in clear, the device on both sides and the `enforcement` facets to remediate — for the alert that opened the ticket, so there is no need to guess it from the device or the title. The response carries nothing from the ticket itself; read the ticket with `getTicket`. A 404 is final and means there is nothing to remediate here — either the ticket is not a compliance ticket, or its alert is no longer raised because the device came back into compliance; a retry returns the same 404 and no other endpoint finds the alert. A compliance ticket is closed automatically by the compliance computation once the device complies.","operationId":"getComplianceAlertDetailsForTicket","parameters":[{"name":"ticketId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetComplianceAlertDetails_Output"}}}}},"summary":"Get the compliance alert a ticket was opened for, with its full remediation context","tags":["Compliance"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/compliance/alerts/filters-options":{"get":{"description":"Return every criterion a compliance alert filter accepts — each with its `key`, `valueType`, allowed operations and live company values (the devices, platforms and owners that currently have an alert). This is the vocabulary for `searchComplianceAlerts`: use a criterion `key` as the filter key and one of its `values` inside the clause (`{\"<key>\":{\"operationType\":\"INCLUDE\",\"values\":[\"<value>\"]}}`). Call this first whenever you are unsure a criterion or a value exists — `searchComplianceAlerts` rejects an unknown key with 400. `ownerId` values are employee ids; resolve their names with `getEmployees`.","operationId":"getComplianceAlertsFilterCatalog","parameters":[],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetComplianceAlertsFilterCatalog_Output"}}}}},"summary":"Get the compliance alert filter catalog","tags":["Compliance"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/compliance/alert-rules":{"get":{"description":"Return the compliance rules of your company — the \"Issue Triggers\" page of the cockpit. One rule per compliance type (e.g. MDM_ENROLLMENT, MDM_ONLINE, MDM_CONTROL_ENCRYPTION); for each of its statuses, the cockpit shows Off, Create Issue or Create Issue and Ticket: a status in `nonCompliantStatus` raises an issue, and one also in `ticketCreationStatus` opens a ticket too. An MDM_CONTROL_* rule with `canEnable: false` has no enabled MDM control of its category, so nothing it lists can fire. Change a rule with `updateComplianceAlertRule` (by its `id`). The ticket defaults, the exceptions and whether auto-remediation is on are in `getComplianceSettings`. To list the devices currently alerting under these rules, use `getComplianceAlerts`.","operationId":"getComplianceAlertRules","parameters":[],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetComplianceAlertRules_Output"}}}}},"summary":"Get all compliance alert rules","tags":["Compliance"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}},"post":{"description":"Create a compliance alert rule for the given type. Each (company, type) pair is unique — calling this for an existing type overwrites its `nonCompliantStatus`, and its `ticketCreationStatus` when you send one. Every rule type already exists once a device was checked, so prefer `updateComplianceAlertRule` with the `id` from `getComplianceAlertRules`.","operationId":"createComplianceAlertRule","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateComplianceAlertRuleBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ComplianceAlertRuleResponse_Output"}}}}},"summary":"Create or upsert a compliance alert rule","tags":["Compliance"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/compliance/alert-rules/{ruleId}":{"put":{"description":"Set, per status of one compliance rule, what the cockpit shows as Off / Create Issue / Create Issue and Ticket: `nonCompliantStatus` lists every status that raises an issue, `ticketCreationStatus` the ones among them that also open a ticket. Send the full lists — read the rule with `getComplianceAlertRules` first and edit them. Omitting `ticketCreationStatus` keeps the ticket statuses the rule already has. An empty `nonCompliantStatus` turns the rule off. Every device the rule covers is recomputed, so issues and tickets follow within minutes.","operationId":"updateComplianceAlertRule","parameters":[{"name":"ruleId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateComplianceAlertRuleBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ComplianceAlertRuleResponse_Output"}}}}},"summary":"Update a compliance alert rule","tags":["Compliance"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/tasks":{"get":{"description":"Return a paginated list of tasks (child tickets) for your company. Pass a task id to getTicket to fetch that single task.","operationId":"getTasks","parameters":[{"name":"page","required":false,"in":"query","description":"Page number","schema":{"minimum":1,"maximum":9007199254740991,"default":1,"type":"number"}},{"name":"perPage","required":false,"in":"query","description":"Number of items per page (max 100)","schema":{"minimum":1,"maximum":100,"default":50,"type":"number"}},{"name":"status","required":false,"in":"query","schema":{"enum":["PENDING","IN_PROGRESS","COMPLETED","CANCELLED"],"type":"string"}},{"name":"priority","required":false,"in":"query","schema":{"enum":["LOW","MEDIUM","HIGH"],"type":"string"}},{"name":"assigneeEmployeeId","required":false,"in":"query","description":"Filter by assignee employee ID","schema":{"type":"string"}},{"name":"parentTicketId","required":false,"in":"query","description":"Filter by parent ticket ID","schema":{"type":"string"}},{"name":"dueDate","required":false,"in":"query","schema":{"enum":["OVERDUE","TODAY","THIS_WEEK","NO_DUE_DATE"],"type":"string"}},{"name":"tagIds","required":false,"in":"query","description":"Filter tasks by tag ids","schema":{"type":"array","items":{"type":"string"}}},{"name":"searchTerm","required":false,"in":"query","description":"Filter tasks by title","schema":{"minLength":1,"type":"string"}},{"name":"sortBy","required":false,"in":"query","schema":{"enum":["status","priority","reference","dueDate","title"],"type":"string"}},{"name":"sortDirection","required":false,"in":"query","schema":{"enum":["ASC","DESC"],"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetTasks_Output"}}}}},"summary":"Get all tasks","tags":["Tasks"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}},"post":{"description":"Create a manual task on an existing ticket. Tasks cannot be added to onboarding tickets (whose tasks are managed automatically).","operationId":"createTask","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTaskBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaskOutput_Output"}}}}},"summary":"Create a task","tags":["Tasks"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/tasks/schedule":{"post":{"description":"Plan work for later on the ticket you are currently working: creates a dormant task that wakes on the given date, instead of writing \"I will check back on Monday\" in a comment and forgetting. System agent transport only — refused for a human MCP token or a REST API key. You may only schedule on the ticket you are the agent of, onboarding tickets included. The task stays hidden for its whole life, asleep or awake: it never shows in the ticket, its task lists or its status, and nothing has to close it. When it wakes, your run on the ticket receives its title and description — there is no separate prompt field, write what to do, not just a title. To create a task that should run now instead of later, use createTask.","operationId":"scheduleTask","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScheduleTaskBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaskOutput_Output"}}}}},"summary":"Schedule a dormant task for later on your own ticket","tags":["Tasks"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/tasks/{taskId}/status":{"post":{"description":"Mark a task as COMPLETED or CANCELLED. A task that completes by executing its intent refuses COMPLETED with a 403 `TaskLockedByTypeError` whose message names the operation to call instead (`executeEquipmentOrderIntent` for an EQUIPMENT_ORDER task, `executeEmployeeCreationIntent` for an EMPLOYEE_CREATION task, `executeEmailAccountIntent` for an EMAIL_ACCOUNT task, `executeSaasSelectionIntent` for a SAAS_SELECTION task); CANCELLED stays open. The admin-managed steps of an onboarding ticket are refused too — an onboarding step closes by doing its work, not by marking its task done — and so is cancelling an automatic task of an onboarding ticket that carries no type. For the Equipment task of an onboarding, use `executeOnboardingEquipment` instead: it places the order or assigns stock and then closes both the step and this task. Provide the parent ticketId in the body.","operationId":"updateTaskStatus","parameters":[{"name":"taskId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateTaskStatusBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaskOutput_Output"}}}}},"summary":"Update task status","tags":["Tasks"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/tasks/{taskId}/assignee":{"post":{"description":"Assign a task to an employee. Provide the parent ticketId in the body.","operationId":"updateTaskAssignee","parameters":[{"name":"taskId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateTaskAssigneeBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaskOutput_Output"}}}}},"summary":"Update task assignee","tags":["Tasks"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/tickets":{"get":{"description":"Return a paginated list of your company tickets — top-level tickets only; list tasks with `getTasks`. `searchTerm` matches a case-insensitive substring of the title or description, or a ticket reference (`IT-1741` or `1741`) — the way to turn a displayed reference into the 24-character ticket `id` the other ticket endpoints take. `assigneeEmployeeId` also returns tickets with an open task assigned to that employee. To count tickets, one total or a breakdown of up to 20 queries (by status, priority, tag, assignee), use `countTickets` instead.","operationId":"getTickets","parameters":[{"name":"page","required":false,"in":"query","description":"Page number","schema":{"minimum":1,"maximum":9007199254740991,"default":1,"type":"number"}},{"name":"perPage","required":false,"in":"query","description":"Number of items per page (max 100)","schema":{"minimum":1,"maximum":100,"default":50,"type":"number"}},{"name":"status","required":false,"in":"query","schema":{"enum":["PENDING","IN_PROGRESS","COMPLETED","CANCELLED"],"type":"string"}},{"name":"priority","required":false,"in":"query","schema":{"enum":["LOW","MEDIUM","HIGH"],"type":"string"}},{"name":"searchTerm","required":false,"in":"query","description":"Filter tickets by title","schema":{"minLength":1,"type":"string"}},{"name":"assigneeEmployeeId","required":false,"in":"query","description":"Filter by assignee employee ID","schema":{"type":"string"}},{"name":"tagIds","required":false,"in":"query","description":"Filter tickets by tag ids","schema":{"type":"array","items":{"type":"string"}}},{"name":"sortBy","required":false,"in":"query","schema":{"enum":["status","priority","reference","title","tasksCount"],"type":"string"}},{"name":"sortDirection","required":false,"in":"query","schema":{"enum":["ASC","DESC"],"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetTickets_Output"}}}}},"summary":"Get all tickets","tags":["Tickets"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}},"post":{"description":"Create a ticket for your company. Only `title` is required, and there is no description field on creation: set the ticket description afterwards with `updateTicket`, or post the details with `createTicketComment`. Link the device, employee or other records it concerns with `linkTicketRelatedObject`. To open the ticket later rather than now (an onboarding step that must not start before a date), the system agent passes `wakeDate` (not with `requester`): the ticket sleeps, hidden from everyone and from `getTickets`, then wakes as an ordinary pending ticket on that date. Keep its `id`: `getTicket` returns it to the agent that created it. To delay work on an existing ticket instead, use `scheduleTask`.","operationId":"createTicket","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTicketBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TicketOutput_Output"}}}}},"summary":"Create a ticket","tags":["Tickets"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/tickets/count":{"post":{"description":"Return only numbers: `{\"counts\":{\"<label>\":<number>}}`, one per labelled query. Use it for any how-many question about tickets, one total or a breakdown (by status, priority, tag, assignee) with one query per bucket, instead of calling `getTickets` once per bucket. A query takes the `status`, `priority`, `searchTerm`, `assigneeEmployeeId` and `tagIds` of `getTickets`, and counts what `getTickets` would return for it (`pagination.totalElements`): top-level tickets only, so tasks are not counted. To list the tickets behind a count, use `getTickets`.","operationId":"countTickets","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CountTicketsBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CountTickets_Output"}}}}},"summary":"Count tickets for up to 20 queries in one call","tags":["Tickets"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/tickets/{ticketId}":{"get":{"description":"Return details for a specific ticket. A task is a child ticket — pass a task id here to fetch a single task. A sleeping ticket (created with a `wakeDate`) is only returned to the agent that created it, until it wakes.","operationId":"getTicket","parameters":[{"name":"ticketId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TicketOutput_Output"}}}}},"summary":"Get a ticket by ID","tags":["Tickets"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}},"patch":{"description":"Partially update a ticket. Only the provided fields are changed (title, description, priority, dueDate, assignee, tags). Use updateTicketStatus to change the status.","operationId":"updateTicket","parameters":[{"name":"ticketId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateTicketBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TicketOutput_Output"}}}}},"summary":"Update a ticket","tags":["Tickets"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/tickets/{ticketId}/status":{"post":{"description":"Set the status of an existing ticket. Its tasks are left as they are — close each one with `updateTaskStatus`. A ticket whose status follows its tasks (onboarding and offboarding tickets) is refused with 403.","operationId":"updateTicketStatus","parameters":[{"name":"ticketId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateTicketStatusBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TicketOutput_Output"}}}}},"summary":"Update ticket status","tags":["Tickets"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/tickets/{ticketId}/assignee":{"post":{"description":"Assign a ticket to an employee. The assignee is a person; to put an AI agent on the ticket or take it off, use `updateTicketAiAgent` instead.","operationId":"updateTicketAssignee","parameters":[{"name":"ticketId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateTicketAssigneeBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TicketOutput_Output"}}}}},"summary":"Update ticket assignee","tags":["Tickets"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/tickets/{ticketId}/ai-agent":{"post":{"description":"Put an AI agent on a ticket, or take the one currently on it off by passing `aiAgentId: null`. The AI agent is the autonomous agent working the ticket, not its assignee — to assign the ticket to a person, use `updateTicketAssignee` instead. An agent puts itself on a ticket by passing its own agent id, and calls this with null to take itself off a ticket it is handing back to the team.","operationId":"updateTicketAiAgent","parameters":[{"name":"ticketId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateTicketAiAgentBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TicketOutput_Output"}}}}},"summary":"Update the AI agent on a ticket","tags":["Tickets"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/tickets/{ticketId}/priority":{"post":{"description":"Update the priority of an existing ticket.","operationId":"updateTicketPriority","parameters":[{"name":"ticketId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateTicketPriorityBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TicketOutput_Output"}}}}},"summary":"Update ticket priority","tags":["Tickets"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/tickets/{ticketId}/comments":{"post":{"description":"Create a comment on a ticket. Comments are INTERNAL by default (team-only, never shown to the requester); pass visibility PUBLIC to post a requester-facing reply. Set taskId to reference the ticket task the comment concerns, and mention people in the text with @[Display Name](employee:<employeeId>) or @[Display Name](external_admin:<clerkUserId>) to notify them. Pass fileIds to attach files uploaded beforehand; a PUBLIC comment sends them to the requester by email.","operationId":"createTicketComment","parameters":[{"name":"ticketId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTicketCommentBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TicketCommentOutput_Output"}}}}},"summary":"Create a ticket comment","tags":["Tickets"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/tickets/{ticketId}/related":{"post":{"description":"Attach a device, employee, SaaS identity, order, shipment or SaaS application to the ticket. For `IDENTITY` pass the SaaS identity id (`identityId` from `getEmployeeSaasIdentities`), for `COMPANY_SAAS_APPLICATION` the company SaaS application id (`id` from `getSaas`). The response carries the `linkId` that `unlinkTicketRelatedObject` takes. The typed-task operations and `startAgentOnboardingTicket` already link what they create to the task and to the ticket holding it: link only other objects with this operation.","operationId":"linkTicketRelatedObject","parameters":[{"name":"ticketId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkTicketRelatedObjectBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkedTicketRelatedObject_Output"}}}}},"summary":"Link a related object to a ticket","tags":["Tickets"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/tickets/{ticketId}/related/{linkId}":{"delete":{"description":"Detach a previously linked object from the ticket, using the linkId returned when listing or linking.","operationId":"unlinkTicketRelatedObject","parameters":[{"name":"ticketId","required":true,"in":"path","schema":{"type":"string"}},{"name":"linkId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnlinkTicketRelatedObjectResult_Output"}}}}},"summary":"Unlink a related object from a ticket","tags":["Tickets"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/tickets/{ticketId}/subscribers":{"post":{"description":"Add one or more subscribers to an existing ticket.","operationId":"addTicketSubscribers","parameters":[{"name":"ticketId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddTicketSubscribersBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TicketSubscribersOutput_Output"}}}}},"summary":"Add subscribers to a ticket","tags":["Tickets"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}},"delete":{"description":"Remove a subscriber from an existing ticket.","operationId":"removeTicketSubscriber","parameters":[{"name":"ticketId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemoveTicketSubscriberBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TicketSubscribersOutput_Output"}}}}},"summary":"Remove a subscriber from a ticket","tags":["Tickets"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}},"get":{"description":"Return all subscribers for a specific ticket.","operationId":"listTicketSubscribers","parameters":[{"name":"ticketId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListTicketSubscribersOutput_Output"}}}}},"summary":"List subscribers of a ticket","tags":["Tickets"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/ticket-tags":{"get":{"description":"Return all ticket tags defined for your company. Use their ids to tag a ticket or task.","operationId":"listTicketTags","parameters":[],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListTicketTagsOutput_Output"}}}}},"summary":"List ticket tags","tags":["TicketTags"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}},"post":{"description":"Create a new ticket tag for your company.","operationId":"createTicketTag","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTicketTagBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TicketTagOutput_Output"}}}}},"summary":"Create a ticket tag","tags":["TicketTags"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/ticket-tags/{tagId}":{"patch":{"description":"Rename an existing ticket tag.","operationId":"updateTicketTag","parameters":[{"name":"tagId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateTicketTagBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TicketTagOutput_Output"}}}}},"summary":"Update a ticket tag","tags":["TicketTags"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}},"delete":{"description":"Delete a ticket tag. It is removed from every ticket and task that carried it.","operationId":"deleteTicketTag","parameters":[{"name":"tagId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteTicketTagResult_Output"}}}}},"summary":"Delete a ticket tag","tags":["TicketTags"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/software":{"get":{"description":"Return the list of software titles managed or distributed by your company (the company-wide catalog) with id, name, platform, source, installation type, and target method. To list the software actually installed on a specific device, use `getDeviceSoftware` instead. `autoUpdatePackage` applies to iOS and iPadOS App Store apps only and `autoInstallUpdate` to Fleet-maintained apps only. To tell whether a Fleet-maintained app is held on an older version, use `getSoftware`.","operationId":"getSoftwares","parameters":[{"name":"page","required":false,"in":"query","description":"Page number","schema":{"minimum":1,"maximum":9007199254740991,"default":1,"type":"number"}},{"name":"perPage","required":false,"in":"query","description":"Number of items per page (max 100)","schema":{"minimum":1,"maximum":100,"default":50,"type":"number"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetSoftwares_Output"}}}}},"summary":"Get all softwares","tags":["Softwares"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/software/vulnerabilities":{"get":{"description":"Return the paginated list of CVE vulnerabilities detected across your fleet, with CVSS scores, EPSS probabilities, and host counts. Use `getVulnerability` for one CVE's full details. To list the vulnerable software installed on a single device, use `getDeviceSoftware` with its `vulnerable` filter.","operationId":"getVulnerabilities","parameters":[{"name":"exploit","required":false,"in":"query","description":"Filter by known exploit availability","schema":{"type":"boolean"}},{"name":"query","required":false,"in":"query","description":"Matches CVE ids only: one full id or a part of one, such as `CVE-2026-` or `CVE-2026-1007`. Software names match nothing.","schema":{"type":"string"}},{"name":"orderDirection","required":false,"in":"query","description":"Order direction","schema":{"enum":["asc","desc"],"type":"string"}},{"name":"orderKey","required":false,"in":"query","description":"Field to order results by","schema":{"enum":["cve","cvss_score","epss_probability","cve_published","created_at","hosts_count"],"type":"string"}},{"name":"page","required":false,"in":"query","description":"Page number","schema":{"type":"number"}},{"name":"perPage","required":false,"in":"query","description":"Number of items per page (max 100)","schema":{"type":"number"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetVulnerabilities_Output"}}}}},"summary":"List vulnerabilities","tags":["Softwares"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/software/vulnerability/{cve}":{"get":{"description":"Return full details for a single CVE detected on at least one device of your fleet, including the affected OS versions and software titles. Accepts the CVE ids `getVulnerabilities` returns: a CVE detected on no device answers 404, and so can a listed CVE whose details are not published yet (its `getVulnerabilities` row is then all there is). To check several CVEs against the fleet, list them with `getVulnerabilities` and compare, narrowing with its `query` filter (one CVE id or a shared prefix such as `CVE-2026-` per call), rather than calling this endpoint once per CVE.","operationId":"getVulnerability","parameters":[{"name":"cve","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetVulnerability_Output"}}}}},"summary":"Get a vulnerability by CVE","tags":["Softwares"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/software/{softwareId}":{"get":{"description":"Return software details for the given software ID, including targeting details and the install, uninstall and post-install scripts Fleet runs on the device. Use the scripts to diagnose a failed install (see `getSoftwareInstallLogs` for the failure output). The scripts are null for App Store / VPP software, which installs via an MDM command and has no scripts. Only the first package of the title is reported, so a title with several packages may run a different script on some devices. To fix a broken script, use `updateSoftwareScripts`. For a Fleet-maintained app, `pinnedVersion` says whether its installer follows new versions (null), stays on one version (\"3.18.25\") or stays inside a major (\"^4\"), and `fleetMaintainedVersions` lists the versions Fleet holds, newest first. `autoUpdatePackage` applies to iOS and iPadOS App Store apps only and `autoInstallUpdate` to Fleet-maintained apps only, so `false` on another source does not mean the app is never updated.","operationId":"getSoftware","parameters":[{"name":"softwareId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"Get a software by ID","tags":["Softwares"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}},"delete":{"description":"Delete ONE software from your company catalog and remove it from the fleet (uninstalling it from targeted devices). This is irreversible.","operationId":"deleteSoftware","parameters":[{"name":"softwareId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteSoftwareResult_Output"}}}}},"summary":"Delete a software","tags":["Softwares"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}},"put":{"description":"Update ONE software's targeting and settings. Targeting is required: set `targetMethod` to `All` (every device) or `DeviceGroup` with a non-empty `deviceGroupIds`; with `DeviceGroup` you can also pass `excludeDeviceGroupIds` to subtract device groups from the targeted set (devices in an excluded group never receive the software). Optional settings: selfService, autoUpdateSoftware, autoUpdatePolicies, automaticInstall, installDuringSetup, the auto-update window, and the patch window of automatic updates (patchWindow). Changing targeting can uninstall the software from devices that lose it. Use `simulateSoftwareTargetCount` to preview the reach first. This endpoint does NOT accept install scripts, and because targeting is mandatory here it always rewrites it — including `excludeDeviceGroupIds`, which resets to none when omitted — so to change a script and nothing else, use `updateSoftwareScripts` instead.","operationId":"updateSoftware","parameters":[{"name":"softwareId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"Update a software","tags":["Softwares"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/software/{softwareId}/devices":{"get":{"description":"Return the paginated list of devices targeted by ONE software, each with its install status and installed version. To list the software on ONE device instead, use `getDeviceSoftware`.","operationId":"getSoftwareDevices","parameters":[{"name":"softwareId","required":true,"in":"path","schema":{"type":"string"}},{"name":"page","required":false,"in":"query","description":"Page number","schema":{"minimum":1,"maximum":9007199254740991,"default":1,"type":"number"}},{"name":"perPage","required":false,"in":"query","description":"Number of items per page (max 100)","schema":{"minimum":1,"maximum":100,"default":50,"type":"number"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetSoftwareDevices_Output"}}}}},"summary":"List devices targeted by a software","tags":["Softwares"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/software/sync":{"post":{"description":"Trigger a resync of your company software catalog from the MDM provider (Fleet): refreshes the persisted software list and their per-device install state. Use this after changes made directly in the MDM provider are not yet reflected. To resync ONE device instead, use `syncDeviceSoftware`.","operationId":"syncCompanySoftwares","parameters":[],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SyncCompanySoftwaresResult_Output"}}}}},"summary":"Sync the company software catalog","tags":["Softwares"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/software/simulate-target-count":{"post":{"description":"Preview how many devices a given targeting would match (platform + globalTarget or a list of device group IDs), without saving anything. Use this before updating a software’s targeting.","operationId":"simulateSoftwareTargetCount","parameters":[],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SimulateSoftwareTargetCount_Output"}}}}},"summary":"Simulate a software target count","tags":["Softwares"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/software/target-counts":{"post":{"description":"Return, for each of the given software IDs, the number of devices currently targeted by that software. To preview a not-yet-saved targeting instead, use `simulateSoftwareTargetCount`.","operationId":"getSoftwareTargetCounts","parameters":[],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResolveSoftwareTargetCounts_Output"}}}}},"summary":"Get target device counts for softwares","tags":["Softwares"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/software/{softwareId}/scripts":{"patch":{"description":"Replace the install, uninstall and/or post-install script of ONE custom-package software. Send at least one; omitted scripts are left untouched and nothing else changes (targeting, self-service, auto-update, setup experience). Only custom packages qualify — App Store / VPP, Fleet-maintained apps and IPA are rejected (Fleet re-derives FMA scripts on every update, so an edit there would silently evaporate). The new script runs on EVERY device this software targets, and Fleet cancels all pending installs for the title as soon as a package field changes, so queued installs must be retried. Use it only when the script is wrong for everyone — e.g. an .exe missing its silent-install flag, or an MSI script treating exit 3010/1641 (success, reboot required) as a failure. For one device, use `runDeviceScript`. Read the current scripts with `getSoftware`, show the user the exact before/after diff, and get explicit confirmation before calling.","operationId":"updateSoftwareScripts","parameters":[{"name":"softwareId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"Update a software's install scripts","tags":["Softwares"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/software/device-counts":{"post":{"description":"Return, for each of the given software IDs, how many devices have it installed, in progress, or failed. Use this for an install-health overview across softwares.","operationId":"getSoftwareDeviceCounts","parameters":[],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetSoftwareDeviceCounts_Output"}}}}},"summary":"Get install status counts for softwares","tags":["Softwares"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/billing-profiles":{"get":{"description":"Return the company billing profiles. Use an eligible profile id when creating an order.","operationId":"getBillingProfiles","parameters":[],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetBillingProfiles_Output"}}}}},"summary":"Get all billing profiles","tags":["BillingProfiles"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/ai-usage":{"get":{"description":"Return the AI credits the company has consumed: the period total, a breakdown per feature (credits, metered generations and share of the total, highest spender first) and a per-day series. Defaults to the current UTC calendar month; pass `from` and `to` for another window. The AI usage page in the cockpit anchors its period on the subscription start date instead, so figures can differ for a company whose billing cycle does not start on the 1st.","operationId":"getAiUsage","parameters":[{"name":"from","required":false,"in":"query","description":"Start of the period, ISO 8601","schema":{"format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$","type":"string"}},{"name":"to","required":false,"in":"query","description":"End of the period, ISO 8601","schema":{"format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$","type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetAiUsage_Output"}}}}},"summary":"Get the company AI credit usage","tags":["AiUsage"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/orders":{"get":{"description":"Return the list of orders for your company, most recent first. Pass `employeeId` to read the orders placed for one person instead of paging through the company: stock orders, which carry no employee, are then left out. Pass `reference` to read the one order carrying that reference, stock orders included. Resolve a name to an id with `getEmployees` first — never enumerate the company to find one order.","operationId":"getOrders","parameters":[{"name":"page","required":false,"in":"query","description":"Page number","schema":{"minimum":1,"maximum":9007199254740991,"default":1,"type":"number"}},{"name":"perPage","required":false,"in":"query","description":"Number of items per page (max 100)","schema":{"minimum":1,"maximum":100,"default":50,"type":"number"}},{"name":"employeeId","required":false,"in":"query","description":"Return only the orders placed for this employee. Stock orders carry no employee and are excluded.","schema":{"pattern":"^[a-f\\d]{24}$","type":"string"}},{"name":"reference","required":false,"in":"query","description":"Return only the order carrying this reference (e.g. \"HI4VBO\"), whoever it was placed for.","schema":{"minLength":1,"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetOrders_Output"}}}}},"summary":"Get orders, optionally narrowed to one employee or one reference","tags":["Orders"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}},"post":{"description":"Create a catalog order (V2) for your company — stock replenishment, or equipment bought outside an onboarding. To equip a joiner and close the Equipment step of their onboarding, use `executeOnboardingEquipment` instead: this endpoint places the order without touching the onboarding or its ticket. To order equipment as a task a ticket tracks, use `createEquipmentOrderIntent` then `executeEquipmentOrderIntent`. This is a real purchase, not a quote or a draft: the order is placed against `data.billingProfileId` when the call returns (`data.status` must be PLACED), and calling it again orders again — the only duplicate guard refuses the same products for the same employee within five minutes, and a stock order (no `employeeId`) is never checked. `countryCode` is required in practice: find products with `searchCatalogProducts` for that country, take the variant and supplier ids from `getCatalogProduct`, and the billing profile from `getBillingProfiles`. An ineligible billing profile or products priced in different currencies are refused too.","operationId":"createOrder","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrderBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatedOrder_Output"}}}}},"summary":"Create an order","tags":["Orders"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/orders/{orderId}":{"get":{"description":"Return the order details for the given order ID.","operationId":"getOrder","parameters":[{"name":"orderId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetOrder_Output"}}}}},"summary":"Get an order by ID","tags":["Orders"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/orders/{orderId}/custom-fields":{"get":{"description":"Return all Active custom field definitions for the order, each paired with the current stored value (or null when unset). For SELECT / MULTI_SELECT fields the `options` catalog is included so you can map option ids to labels.","operationId":"getOrderCustomFields","parameters":[{"name":"orderId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetOrderCustomFields_Output"}}}}},"summary":"Get order custom fields","tags":["Orders"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/orders/{orderId}/custom-fields/{customFieldId}":{"put":{"description":"Set or overwrite a custom field value on an order. Idempotent. Returns the updated field (definition + value). For SELECT supply the option id (string); for MULTI_SELECT supply an array of option ids. Option ids can be read from the `getOrderCustomFields` endpoint.","operationId":"setOrderCustomFieldValue","parameters":[{"name":"orderId","required":true,"in":"path","schema":{"type":"string"}},{"name":"customFieldId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetOrderCustomFieldValueBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrderCustomFieldItem_Output"}}}}},"summary":"Set an order custom field value","tags":["Orders"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}},"delete":{"description":"Remove the stored value for a custom field on an order. Returns the updated field (value reset to null).","operationId":"clearOrderCustomFieldValue","parameters":[{"name":"orderId","required":true,"in":"path","schema":{"type":"string"}},{"name":"customFieldId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrderCustomFieldItem_Output"}}}}},"summary":"Clear an order custom field value","tags":["Orders"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/equipment-order-intents":{"post":{"description":"Plan equipment for someone as a task the ticket tracks: a catalog order to place and/or devices and accessories to hand over from stock. Creates the intent and its EQUIPMENT_ORDER task, and places nothing yet — `executeEquipmentOrderIntent` does. Pass the ticket the work belongs to as `parentTicketId`; without one Primo opens a ticket for the employee to hold the task. `createTicket` and `createTask` cannot make a typed task. Returns the intent `id`, its `taskId` and the `ticketId` holding it. The task cannot be marked done by hand; it completes when the intent executes. An equipment order cannot be scheduled: a `scheduleDate` is refused with `SCHEDULE_NOT_SUPPORTED_FOR_TYPE`, since nothing would place the order at that date — create the intent now and execute it when the order is due. Build `order` as for `createOrder`: products from `searchCatalogProducts` and `getCatalogProduct`, the billing profile from `getBillingProfiles`, the address from `getCompanyAddresses` or the employee record. `executeOnboardingEquipment` is the legacy twin: use it only for an onboarding still on the classic Equipment step, which it closes. Use the equipment order intent for equipment work tracked as a task on a ticket (an EQUIPMENT_ORDER task) — it never closes an onboarding Equipment step. Refused with `PARENT_TICKET_IS_TYPED` or `PARENT_TICKET_IS_A_TASK` (pass the untyped ticket instead), `PARENT_TICKET_NOT_FOUND`, `EMPLOYEE_NOT_FOUND`, and `INVENTORY_ASSIGNMENT_REQUIRES_EMPLOYEE` for stock without an employee.","operationId":"createEquipmentOrderIntent","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEquipmentOrderIntentBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EquipmentOrderIntent_Output"}}}}},"summary":"Create an equipment order intent","tags":["Orders"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/equipment-order-intents/{intentId}":{"patch":{"description":"Change what an equipment order intent will do before it executes. Only the fields you send change; `order` and `assignedFromInventory` are replaced whole, and null clears one. The employee cannot change: create a new intent for someone else. Refused with `INTENT_ALREADY_EXECUTED` once executed, `TICKET_CLOSED` when its task is completed or cancelled, `INVENTORY_ASSIGNMENT_REQUIRES_EMPLOYEE` for stock on an intent with no employee. Stock ids are checked against the company stock on execute. An equipment order cannot be scheduled, so there is no `scheduleDate` here: execute the intent when the order is due. `executeOnboardingEquipment` is the legacy twin: use it only for an onboarding still on the classic Equipment step, which it closes. Use the equipment order intent for equipment work tracked as a task on a ticket (an EQUIPMENT_ORDER task) — it never closes an onboarding Equipment step.","operationId":"updateEquipmentOrderIntent","parameters":[{"name":"intentId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateEquipmentOrderIntentBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EquipmentOrderIntent_Output"}}}}},"summary":"Update an equipment order intent","tags":["Orders"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/equipment-order-intents/{intentId}/execute":{"post":{"description":"Carry out an equipment order intent: places its catalog order — a real purchase against its billing profile — hands over its stock items, sends the enrollment request when asked, links the order and devices to its task and to the ticket holding it, and completes the task. This is the only way to complete an EQUIPMENT_ORDER task: `updateTaskStatus` refuses it with `TaskLockedByTypeError` naming this operation. Safe to retry: an intent executed earlier answers `outcome: ALREADY_EXECUTED` and orders nothing again, and an order placed by an attempt that failed later is not placed twice. Refused with `TICKET_SCHEDULED` before a scheduled task wakes up, `TICKET_CLOSED`, `DUPLICATE_ORDER` (same products for the employee within 5 minutes), `EXECUTION_IN_PROGRESS`, `NOTHING_TO_EXECUTE`, `INVENTORY_ITEM_NOT_FOUND`, `INVENTORY_DEVICE_RETIRED`, `INVENTORY_ASSIGNMENT_FAILED`; a refusal leaves the task PENDING with an internal comment on the ticket. `executeOnboardingEquipment` is the legacy twin: use it only for an onboarding still on the classic Equipment step, which it closes. Use the equipment order intent for equipment work tracked as a task on a ticket (an EQUIPMENT_ORDER task) — it never closes an onboarding Equipment step.","operationId":"executeEquipmentOrderIntent","parameters":[{"name":"intentId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExecuteEquipmentOrderIntentResult_Output"}}}}},"summary":"Execute an equipment order intent","tags":["Orders"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/saas":{"get":{"description":"Return the list of SaaS applications for your company, regardless of their approval status. Each item carries the `id` to pass as `saasId` to the other SaaS endpoints, the application name, its `approvalStatus`, its `connectionStatus`, its tags and how many identities it holds.\n\nPass `search` to resolve an application by name in one call, `approvalStatus` to keep only the applications in a given status, and `isEmailProvider: true` to resolve the one application the company's mailboxes live in.\n\nTo read the identities of one employee across every application, use `getEmployeeSaasIdentities` instead — this list only counts them.","operationId":"getSaas","parameters":[{"name":"isEmailProvider","required":false,"in":"query","description":"Pass true to keep only the company's email provider. A company has at most one.","schema":{"type":"boolean"}},{"name":"approvalStatus","required":false,"in":"query","description":"Restrict the list to SaaS applications in this approval status.","schema":{"enum":["TO_REVIEW","APPROVED","REJECTED"],"type":"string"}},{"name":"search","required":false,"in":"query","description":"Free-text search on the SaaS application name (case-insensitive, matches on a fragment).","schema":{"type":"string"}},{"name":"page","required":false,"in":"query","description":"Page number","schema":{"type":"number"}},{"name":"perPage","required":false,"in":"query","description":"Number of items per page (max 100)","schema":{"type":"number"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetSaas_Output"}}}}},"summary":"Get all SaaS","tags":["Saas"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/employees/{employeeId}/saas-identities":{"get":{"description":"Return every SaaS identity held by one employee, across all the SaaS applications of your company — use it to answer whether someone has access to a given application, and with which group, role, license and organization unit.\n\nEach entry carries `saasId` (the company SaaS application, to pass to `getSaasById` or `provisionSaasIdentity`), `saasName`, the application `approvalStatus`, `identityId` (to pass to `deprovisionSaasIdentity`), and the assigned entitlements as `{ id, name }` pairs whose `id` is what `provisionSaasIdentity` expects.\n\nIdentities on applications that are not APPROVED are included — they are real accesses discovered by Primo, but they cannot be provisioned or deprovisioned until the application is approved.\n\nTo list the identities of one application rather than of one employee, use `getSaasById` instead.","operationId":"getEmployeeSaasIdentities","parameters":[{"name":"employeeId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetEmployeeSaasIdentities_Output"}}}}},"summary":"Get the SaaS identities of an employee","tags":["Saas"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/saas-identities/unlinked":{"get":{"description":"Return, as a paginated list, the SaaS identities of your company that are linked to no employee and classified as no other kind of account — the identities the cockpit shows as \"To link\" — across every SaaS application at once, whatever its approval status. Each item carries its `id`, `email`, the `saasId` / `saasName` / `approvalStatus` of the application it is on, and `syncedByIntegration`.\n\nUse it to review or clean up the accounts nobody owns: pass the `id`s to `linkSaasIdentities` to give each one its owner, or to `archiveSaasApplicationUsers` or `deleteSaasApplicationUsers`, up to 100 per call. Up to 100 identities per page; read `pagination.totalPages` and page through the rest.\n\nArchiving or deleting an identity whose `syncedByIntegration` is true does not remove the account: the next sync of the integration brings it back. Leave those out and tell the user to remove the accounts in the application itself; Primo drops them at its next sync.\n\nPrefer it over calling `getSaasById` once per application: that returns every identity of one application with its entitlements, so finding the unlinked ones that way takes one call per application.","operationId":"getUnlinkedSaasIdentities","parameters":[{"name":"syncedByIntegration","required":false,"in":"query","description":"Pass false to keep only the identities on applications no integration syncs, true to keep only the others.","schema":{"type":"boolean"}},{"name":"approvalStatus","required":false,"in":"query","description":"Keep only the identities of SaaS applications in this approval status.","schema":{"enum":["TO_REVIEW","APPROVED","REJECTED"],"type":"string"}},{"name":"page","required":false,"in":"query","description":"Page number","schema":{"type":"number"}},{"name":"perPage","required":false,"in":"query","description":"Number of items per page (max 100)","schema":{"type":"number"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetUnlinkedSaasIdentities_Output"}}}}},"summary":"Get the SaaS identities no employee owns, across every application","tags":["Saas"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/saas-identities/batch-link":{"post":{"description":"Link existing SaaS identities (accounts already on an application) to the employees who own them, up to 100 identity → employee pairs per call. Primo links an account to an employee by itself only when the account email equals the employee email; this links the accounts it could not match, such as an alias (`firstname.lastname@`) of an employee whose HR email is `flastname@`.\n\nThe account keeps its own email, becomes an employee account and leaves the \"To link\" list. An identity already linked to another employee moves to the one given. A later integration sync keeps the link. Nothing changes in the application itself.\n\nRead the identities to link from `getUnlinkedSaasIdentities` (its `id`) and the employees from `getEmployees` (its `id`). To record an account Primo does not know yet, use `createSaasIdentity` instead; to have an admin create a new account, use `provisionSaasIdentity`.\n\nWrites are independent and best-effort: the call returns 200 with a `results` manifest reporting `ok` / `error` per item — always inspect `results` rather than relying on the HTTP status to detect partial failures.","operationId":"linkSaasIdentities","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSaasIdentitiesBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSaasIdentitiesResult_Output"}}}}},"summary":"Link SaaS identities to the employees who own them","tags":["Saas"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/saas/{saasId}":{"get":{"description":"Return the SaaS details for the given company SaaS application ID — identities, recent events, contract and provisioning rule.\n\nAn application that is not APPROVED is returned too: read `approvalStatus` before concluding anything from it. It cannot be provisioned, whatever the rest of the payload says. Its `contract` and `rule` are usually `null`, but an application that was approved once and later rejected keeps the contract and rule it had then — treat them as history, not as an active configuration.\n\nTo find the identities no employee owns across every application, use `getUnlinkedSaasIdentities` instead of reading each application here.","operationId":"getSaasById","parameters":[{"name":"saasId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetSaasById_Output"}}}}},"summary":"Get a SaaS by ID","tags":["Saas"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/saas/{saasId}/issues":{"get":{"description":"Return the list of provisioning issues currently flagged by the rule on the given SaaS, including missing access, unexpected access, missing/extra group/role/license assignments and orphaned identities.\n\nIssues are produced by the provisioning rule, so on an application that is not APPROVED they are never current: an empty list means nothing was evaluated rather than that the application is in order, and a non-empty one is what the rule last found while the application was still approved. Read `approvalStatus` and the rule from `getSaasById` before acting on either.","operationId":"getSaasIssues","parameters":[{"name":"saasId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetSaasIssues_Output"}}}}},"summary":"Get the issues flagged for a SaaS","tags":["Saas"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/saas/{saasId}/contract":{"put":{"description":"Replace the contract configuration for the given SaaS. All prices must be expressed for one billing period defined by `billingFrequency` (not annualized).\n\n**`flat_rate` mode** — a single recurring amount covers the whole subscription:\n- `flatRatePrice` must be set.\n- `unlicensedPricePerSeat`, `unlicensedMinimumSeatsBilled`, `licenses[].pricePerSeat` and `licenses[].minimumSeatsBilled` must all be `null`.\n\n**`per_licence` mode** — pricing is broken down per license type:\n- `flatRatePrice` must be `null`.\n- `unlicensedPricePerSeat`, `unlicensedMinimumSeatsBilled`, `licenses[].pricePerSeat` and `licenses[].minimumSeatsBilled` must all be set.\n\nThe `licenses` array must exactly match the licenses defined in the SaaS: every entry must have the same `id` as the corresponding SaaS license (retrieve them via `getSaasById`).","operationId":"updateSaasContract","parameters":[{"name":"saasId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSaasContractBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaasContractResource_Output"}}}}},"summary":"Update a SaaS contract","tags":["Saas"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/saas/{saasId}/rule":{"put":{"description":"Overwrite the draft of the natural-language provisioning rule for this SaaS, and optionally publish it in the same call. You must provide the COMPLETE rule text — this fully replaces the draft, it does not append. Call getSaasById first and re-send the full, edited body. With `publish: true` the new draft goes live immediately, which is the one-call path for a change the user has already confirmed; without it the draft is written but stays offline until publishSaasRule is called.","operationId":"updateSaasRule","parameters":[{"name":"saasId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSaasRuleBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaasRule_Output"}}}}},"summary":"Update a SaaS provisioning rule draft","tags":["Saas"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/saas/{saasId}/rule/publish":{"post":{"description":"Publish the SaaS provisioning rule: copy the current draft to the published text so the agent reads it at runtime when reviewing provisioning for this SaaS. Only call this AFTER the user has reviewed the exact draft in the conversation and explicitly confirmed they want it published — it makes the rule live for provisioning decisions. Call getSaasById first to show the draft and confirm. Fails if no rule exists yet.","operationId":"publishSaasRule","parameters":[{"name":"saasId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaasRule_Output"}}}}},"summary":"Publish a SaaS provisioning rule","tags":["Saas"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/saas/identities/preview":{"post":{"description":"Judge a person against the company's published SaaS rules and return, for each APPROVED application whose rule grants them an account, the groups, roles, licenses and organization units they should get. The same judgement decides what a new hire is preselected for at onboarding and which access gaps an application shows.\n\nThe person is described by attributes, not by an id: they do not need to exist in Primo yet, so it answers for a future hire as well as for an employee. For an existing employee, pass what `getEmployee` and `getEmployeeCustomFields` return for them — the rules may depend on any of it, custom fields included.\n\nIt creates nothing. Each entry carries the `saasId` and the entitlement ids `provisionSaasIdentity` takes, so a proposal built from it can be carried out once approved. An application without a published rule, or whose rule does not grant the person, is absent.\n\nEXPENSIVE: one AI judgement per application with a published rule. Call it once per person, never in a loop or across the directory.","operationId":"previewSaasIdentitiesFromRules","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreviewSaasIdentitiesBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreviewSaasIdentities_Output"}}}}},"summary":"Preview the SaaS accounts the rules grant to a person","tags":["Saas"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/saas/{saasId}/issues/preview":{"post":{"description":"Judge the DRAFT of the provisioning rule of the given SaaS — the text the rule editor shows, published or not — against the whole directory, exactly as publishing it would: every employee compared to the account they hold, and every identity on the SaaS. Returns the persons it would flag, with the issues (missing or unexpected access, groups, roles, licenses and organization units to add or remove), and `compliantCount`, the employees it leaves in order. Same issue types as `getSaasIssues`, which lists what the published rule found.\n\nIt creates and stores nothing, and works whatever the approval status of the SaaS. It reads the saved draft, never a text passed in: save it with `updateSaasRule` first. EXPENSIVE: one AI judgement over the whole directory — call it once per check, never in a loop.","operationId":"previewSaasIssues","parameters":[{"name":"saasId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreviewSaasIssues_Output"}}}}},"summary":"Preview the issues the rule draft of a SaaS raises","tags":["Saas"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/saas/{saasId}/provision":{"post":{"description":"Get an employee an account on a SaaS application, with optional group, role, license and organization unit assignments. The account does not exist yet: this endpoint is what brings it into being.\n\nWhen the application already has the account and you only need Primo to know about it, use `createSaasIdentity` instead — this endpoint would open a provisioning ticket asking an admin to create an account that is already there.\n\nWorks on any APPROVED application. With an API integration the account is created **automatically**; without one a **provisioning task** is raised for an admin to create it by hand, which takes as long as the admin takes — on the ticket given as `ticketId`, or on a new provisioning ticket when none is given. The `provisioningType` field in the response says which path was taken.","operationId":"provisionSaasIdentity","parameters":[{"name":"saasId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProvisionSaasIdentityBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProvisionSaasIdentity_Output"}}}}},"summary":"Ask for an account to be created on a SaaS application","tags":["Saas"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/saas/{saasId}/provisioning-intents":{"post":{"description":"Create, remove or update an employee's account on a SaaS application as a SAAS_PROVISIONING task on a ticket, so the account can be scheduled, cancelled and completed like any task. Pass the untyped ticket the work belongs to, such as an onboarding ticket, as `parentTicketId`; without one Primo opens a ticket for the employee to hold the task. `createTicket` and `createTask` cannot make a typed task.\n\nWith an API integration the account is carried out by Primo, at once or on `scheduleDate`, and the task completes itself. Without one the task waits for an admin, who creates the account by hand and marks the task done, which records the account in Primo. Once a task has created the account, Primo links it to the task and to the ticket holding it. Cancelling the task cancels the account change.\n\nUse `provisionSaasIdentity` or `deprovisionSaasIdentity` for an account change nobody needs to track on a ticket. Returns the intent `id`, its `taskId` and the `ticketId` holding it. Entitlements are `{ id, name }` pairs from `getSaasById`.\n\nRefused with `PARENT_TICKET_IS_TYPED` or `PARENT_TICKET_IS_A_TASK` (pass the untyped ticket instead), `PARENT_TICKET_NOT_FOUND`, `EMPLOYEE_NOT_FOUND`, `CREDENTIALS_RECIPIENT_REQUIRED` for an application that generates a password (create that account from the cockpit), `SAAS_APPLICATION_USER_REQUIRED` for an UPDATE without `identityId`, and `SAAS_APPLICATION_USER_NOT_FOUND` for an `identityId` that belongs to another employee or application.","operationId":"createSaasProvisioningIntent","parameters":[{"name":"saasId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaasProvisioningIntentBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaasProvisioningIntent_Output"}}}}},"summary":"Create a SaaS account task on a ticket","tags":["Saas"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/saas/{saasId}/deprovision":{"post":{"description":"Remove an employee's identity from a SaaS application.\n\nDepending on the SaaS application capabilities, the deprovisioning is either handled **automatically** (via API integration) or **manually** (a deprovisioning ticket is created for an admin to complete).\n\nThe response indicates which path was taken via the `provisioningType` field.","operationId":"deprovisionSaasIdentity","parameters":[{"name":"saasId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeprovisionSaasIdentityBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeprovisionSaasIdentity_Output"}}}}},"summary":"Deprovision a SaaS identity","tags":["Saas"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/saas/{saasId}/reset-password":{"post":{"description":"Replace the password of the employee's identity on this SaaS application and mail the new one to them. The password is never returned, so it cannot be repeated in a ticket, a comment or a reply — report only where it was sent.\n\nThe new password goes to the **personal** email address on the employee record, falling back to their professional one. Resetting the company's **email provider** is the exception: it only ever delivers to the personal address, because the professional mailbox is the account being reset. Without a personal address on the record, that reset is refused.\n\n**There is no manual fallback.** Unlike provisioning, an application with no connected API — or whose integration cannot set a password — is refused outright and no ticket is created. Only Google Workspace and Entra support this today.\n\nThe identity signs in with the new password once and is asked to choose another. Open sessions are left alone. Calling this again issues yet another password and invalidates the one already sent.","operationId":"resetSaasIdentityPassword","parameters":[{"name":"saasId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResetSaasIdentityPasswordBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResetSaasIdentityPassword_Output"}}}}},"summary":"Reset the password of an employee's identity on a SaaS application","tags":["Saas"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/saas/{saasId}/identities":{"post":{"description":"Create the identity record for an account on a SaaS application Primo cannot provision itself, writing it immediately — no provisioning ticket, no task for an admin. Use it when asked to create, add or register an identity, a user or an account on such an application.\n\nIt records an account rather than creating one on the application. When the account still has to be created over there, use `provisionSaasIdentity`.\n\nOnly for applications whose account creation is manual. One whose integration creates accounts itself is rejected with a 400, as is one that is not APPROVED.\n\nPass `employeeId` to attach the account to an employee, which offboarding needs to raise a removal task; pass `email` alone for an account no employee owns. Re-creating a recorded account updates it and keeps its employee.\n\nSend entitlements as IDs from `getSaasById`: a name is resolved only on an application Primo does not already read that entitlement from, and is dropped silently elsewhere.\n\nTo record several accounts on the same application at once — a list of employees onboarding together — use `createSaasIdentities` instead.","operationId":"createSaasIdentity","parameters":[{"name":"saasId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaasIdentityBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaasIdentity_Output"}}}}},"summary":"Create a SaaS identity directly, with no provisioning ticket","tags":["Saas"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/saas/{saasId}/owner":{"put":{"description":"Set the owning employee of the given SaaS application. `ownerId` is the ID of an employee in your company.","operationId":"updateSaasOwner","parameters":[{"name":"saasId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSaasOwnerBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSaasOwnerResult_Output"}}}}},"summary":"Update the owner of a SaaS","tags":["Saas"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/saas/{saasId}/approval-status":{"put":{"description":"Update the approval status of the given SaaS application.\n\nSetting the status to `APPROVED` also enables manual provisioning on the SaaS — a prerequisite for managing manual entitlements (licenses, roles, groups, organization units).","operationId":"updateSaasApprovalStatus","parameters":[{"name":"saasId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSaasApprovalStatusBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSaasApprovalStatusResult_Output"}}}}},"summary":"Update the approval status of a SaaS","tags":["Saas"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/saas/{saasId}/identities/{identityId}/groups/{remoteId}":{"post":{"description":"Put the account into one of the application's groups. A group whose membership the provider does not let Primo change (a distribution list, a mail-enabled security group, a dynamic-membership group) is rejected with a 409.\n\nIt changes what an existing account holds — it never creates one. When the employee has no account on the application yet, use `provisionSaasIdentity`, which takes the entitlements in the same call.\n\nDo not confuse it with `addSaasGroup` / `addSaasRole` / `addSaasLicence` / `addSaasOrganizationUnit` and their `removeSaas…` counterparts: those change the application's catalogue, for everyone, and only on a manually-provisioned application. This one changes which existing catalogue entries one person's account holds.\n\nWith an API integration the change is applied **automatically**; without one a **provisioning ticket** is raised for an admin to carry it out, which takes as long as the admin takes — the response says which path was taken in `provisioningType`. A call that asks for what is already true changes nothing and returns `changed: false`.","operationId":"assignSaasGroup","parameters":[{"name":"saasId","required":true,"in":"path","schema":{"type":"string"}},{"name":"identityId","required":true,"in":"path","schema":{"type":"string"}},{"name":"remoteId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaasIdentityEntitlementAssignment_Output"}}}}},"summary":"Add a SaaS identity to a group","tags":["Saas"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}},"delete":{"description":"Take the account out of one of the application's groups. The account itself is left in place — to remove the account entirely, use `deprovisionSaasIdentity`.\n\nIt changes what an existing account holds — it never creates one. When the employee has no account on the application yet, use `provisionSaasIdentity`, which takes the entitlements in the same call.\n\nDo not confuse it with `addSaasGroup` / `addSaasRole` / `addSaasLicence` / `addSaasOrganizationUnit` and their `removeSaas…` counterparts: those change the application's catalogue, for everyone, and only on a manually-provisioned application. This one changes which existing catalogue entries one person's account holds.\n\nWith an API integration the change is applied **automatically**; without one a **provisioning ticket** is raised for an admin to carry it out, which takes as long as the admin takes — the response says which path was taken in `provisioningType`. A call that asks for what is already true changes nothing and returns `changed: false`.","operationId":"unassignSaasGroup","parameters":[{"name":"saasId","required":true,"in":"path","schema":{"type":"string"}},{"name":"identityId","required":true,"in":"path","schema":{"type":"string"}},{"name":"remoteId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaasIdentityEntitlementAssignment_Output"}}}}},"summary":"Remove a SaaS identity from a group","tags":["Saas"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/saas/{saasId}/identities/{identityId}/roles/{remoteId}":{"post":{"description":"Give the account one of the application's roles.\n\nIt changes what an existing account holds — it never creates one. When the employee has no account on the application yet, use `provisionSaasIdentity`, which takes the entitlements in the same call.\n\nDo not confuse it with `addSaasGroup` / `addSaasRole` / `addSaasLicence` / `addSaasOrganizationUnit` and their `removeSaas…` counterparts: those change the application's catalogue, for everyone, and only on a manually-provisioned application. This one changes which existing catalogue entries one person's account holds.\n\nWith an API integration the change is applied **automatically**; without one a **provisioning ticket** is raised for an admin to carry it out, which takes as long as the admin takes — the response says which path was taken in `provisioningType`. A call that asks for what is already true changes nothing and returns `changed: false`.","operationId":"assignSaasRole","parameters":[{"name":"saasId","required":true,"in":"path","schema":{"type":"string"}},{"name":"identityId","required":true,"in":"path","schema":{"type":"string"}},{"name":"remoteId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaasIdentityEntitlementAssignment_Output"}}}}},"summary":"Give a SaaS identity a role","tags":["Saas"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}},"delete":{"description":"Take one of the application's roles off the account. The account itself is left in place — to remove the account entirely, use `deprovisionSaasIdentity`.\n\nIt changes what an existing account holds — it never creates one. When the employee has no account on the application yet, use `provisionSaasIdentity`, which takes the entitlements in the same call.\n\nDo not confuse it with `addSaasGroup` / `addSaasRole` / `addSaasLicence` / `addSaasOrganizationUnit` and their `removeSaas…` counterparts: those change the application's catalogue, for everyone, and only on a manually-provisioned application. This one changes which existing catalogue entries one person's account holds.\n\nWith an API integration the change is applied **automatically**; without one a **provisioning ticket** is raised for an admin to carry it out, which takes as long as the admin takes — the response says which path was taken in `provisioningType`. A call that asks for what is already true changes nothing and returns `changed: false`.","operationId":"unassignSaasRole","parameters":[{"name":"saasId","required":true,"in":"path","schema":{"type":"string"}},{"name":"identityId","required":true,"in":"path","schema":{"type":"string"}},{"name":"remoteId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaasIdentityEntitlementAssignment_Output"}}}}},"summary":"Take a role off a SaaS identity","tags":["Saas"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/saas/{saasId}/identities/{identityId}/licenses/{remoteId}":{"post":{"description":"Give the account one of the application's licences. A licence is a billed seat: read `contract.licenses[].pricePerSeat` on `getSaasById` for what it costs per billing period before asking for it.\n\nIt changes what an existing account holds — it never creates one. When the employee has no account on the application yet, use `provisionSaasIdentity`, which takes the entitlements in the same call.\n\nDo not confuse it with `addSaasGroup` / `addSaasRole` / `addSaasLicence` / `addSaasOrganizationUnit` and their `removeSaas…` counterparts: those change the application's catalogue, for everyone, and only on a manually-provisioned application. This one changes which existing catalogue entries one person's account holds.\n\nWith an API integration the change is applied **automatically**; without one a **provisioning ticket** is raised for an admin to carry it out, which takes as long as the admin takes — the response says which path was taken in `provisioningType`. A call that asks for what is already true changes nothing and returns `changed: false`.","operationId":"assignSaasLicence","parameters":[{"name":"saasId","required":true,"in":"path","schema":{"type":"string"}},{"name":"identityId","required":true,"in":"path","schema":{"type":"string"}},{"name":"remoteId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaasIdentityEntitlementAssignment_Output"}}}}},"summary":"Give a SaaS identity a licence","tags":["Saas"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}},"delete":{"description":"Take one of the application's licences off the account. The account itself is left in place, and keeps whatever else it holds — to remove the account entirely, use `deprovisionSaasIdentity`.\n\nIt changes what an existing account holds — it never creates one. When the employee has no account on the application yet, use `provisionSaasIdentity`, which takes the entitlements in the same call.\n\nDo not confuse it with `addSaasGroup` / `addSaasRole` / `addSaasLicence` / `addSaasOrganizationUnit` and their `removeSaas…` counterparts: those change the application's catalogue, for everyone, and only on a manually-provisioned application. This one changes which existing catalogue entries one person's account holds.\n\nWith an API integration the change is applied **automatically**; without one a **provisioning ticket** is raised for an admin to carry it out, which takes as long as the admin takes — the response says which path was taken in `provisioningType`. A call that asks for what is already true changes nothing and returns `changed: false`.","operationId":"unassignSaasLicence","parameters":[{"name":"saasId","required":true,"in":"path","schema":{"type":"string"}},{"name":"identityId","required":true,"in":"path","schema":{"type":"string"}},{"name":"remoteId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaasIdentityEntitlementAssignment_Output"}}}}},"summary":"Take a licence off a SaaS identity","tags":["Saas"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/saas/{saasId}/identities/{identityId}/organization-units/{remoteId}":{"post":{"description":"Put the account in one of the application's organization units.\n\nIt changes what an existing account holds — it never creates one. When the employee has no account on the application yet, use `provisionSaasIdentity`, which takes the entitlements in the same call.\n\nDo not confuse it with `addSaasGroup` / `addSaasRole` / `addSaasLicence` / `addSaasOrganizationUnit` and their `removeSaas…` counterparts: those change the application's catalogue, for everyone, and only on a manually-provisioned application. This one changes which existing catalogue entries one person's account holds.\n\nWith an API integration the change is applied **automatically**; without one a **provisioning ticket** is raised for an admin to carry it out, which takes as long as the admin takes — the response says which path was taken in `provisioningType`. A call that asks for what is already true changes nothing and returns `changed: false`.","operationId":"assignSaasOrganizationUnit","parameters":[{"name":"saasId","required":true,"in":"path","schema":{"type":"string"}},{"name":"identityId","required":true,"in":"path","schema":{"type":"string"}},{"name":"remoteId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaasIdentityEntitlementAssignment_Output"}}}}},"summary":"Put a SaaS identity in an organization unit","tags":["Saas"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}},"delete":{"description":"Take the account out of one of the application's organization units. The account itself is left in place — to remove the account entirely, use `deprovisionSaasIdentity`.\n\nIt changes what an existing account holds — it never creates one. When the employee has no account on the application yet, use `provisionSaasIdentity`, which takes the entitlements in the same call.\n\nDo not confuse it with `addSaasGroup` / `addSaasRole` / `addSaasLicence` / `addSaasOrganizationUnit` and their `removeSaas…` counterparts: those change the application's catalogue, for everyone, and only on a manually-provisioned application. This one changes which existing catalogue entries one person's account holds.\n\nWith an API integration the change is applied **automatically**; without one a **provisioning ticket** is raised for an admin to carry it out, which takes as long as the admin takes — the response says which path was taken in `provisioningType`. A call that asks for what is already true changes nothing and returns `changed: false`.","operationId":"unassignSaasOrganizationUnit","parameters":[{"name":"saasId","required":true,"in":"path","schema":{"type":"string"}},{"name":"identityId","required":true,"in":"path","schema":{"type":"string"}},{"name":"remoteId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaasIdentityEntitlementAssignment_Output"}}}}},"summary":"Take a SaaS identity out of an organization unit","tags":["Saas"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/saas/{saasId}/licences":{"post":{"description":"Add a new license to the SaaS catalog. Only allowed when the SaaS license capability is set to MANUAL (i.e. a manually-provisioned SaaS). Returns 409 otherwise.","operationId":"addSaasLicence","parameters":[{"name":"saasId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaasEntitlementMutationBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaasEntitlementList_Output"}}}}},"summary":"Add a license to a SaaS","tags":["Saas"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/saas/{saasId}/licences/{remoteId}":{"put":{"description":"Rename an existing license. `remoteId` is the entitlement ID returned by `getSaasById`. Only allowed when the SaaS license capability is set to MANUAL (i.e. a manually-provisioned SaaS). Returns 409 otherwise.","operationId":"updateSaasLicence","parameters":[{"name":"saasId","required":true,"in":"path","schema":{"type":"string"}},{"name":"remoteId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaasEntitlementMutationBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaasEntitlementList_Output"}}}}},"summary":"Rename a license of a SaaS","tags":["Saas"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}},"delete":{"description":"Remove an existing license. `remoteId` is the entitlement ID returned by `getSaasById`. Only allowed when the SaaS license capability is set to MANUAL (i.e. a manually-provisioned SaaS). Returns 409 otherwise.","operationId":"removeSaasLicence","parameters":[{"name":"saasId","required":true,"in":"path","schema":{"type":"string"}},{"name":"remoteId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaasEntitlementList_Output"}}}}},"summary":"Remove a license from a SaaS","tags":["Saas"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/saas/{saasId}/roles":{"post":{"description":"Add a new role to the SaaS catalog. Only allowed when the SaaS role capability is set to MANUAL (i.e. a manually-provisioned SaaS). Returns 409 otherwise.","operationId":"addSaasRole","parameters":[{"name":"saasId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaasEntitlementMutationBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaasEntitlementList_Output"}}}}},"summary":"Add a role to a SaaS","tags":["Saas"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/saas/{saasId}/roles/{remoteId}":{"put":{"description":"Rename an existing role. `remoteId` is the entitlement ID returned by `getSaasById`. Only allowed when the SaaS role capability is set to MANUAL (i.e. a manually-provisioned SaaS). Returns 409 otherwise.","operationId":"updateSaasRole","parameters":[{"name":"saasId","required":true,"in":"path","schema":{"type":"string"}},{"name":"remoteId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaasEntitlementMutationBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaasEntitlementList_Output"}}}}},"summary":"Rename a role of a SaaS","tags":["Saas"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}},"delete":{"description":"Remove an existing role. `remoteId` is the entitlement ID returned by `getSaasById`. Only allowed when the SaaS role capability is set to MANUAL (i.e. a manually-provisioned SaaS). Returns 409 otherwise.","operationId":"removeSaasRole","parameters":[{"name":"saasId","required":true,"in":"path","schema":{"type":"string"}},{"name":"remoteId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaasEntitlementList_Output"}}}}},"summary":"Remove a role from a SaaS","tags":["Saas"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/saas/{saasId}/groups":{"post":{"description":"Add a new group to the SaaS catalog. Only allowed when the SaaS group capability is set to MANUAL (i.e. a manually-provisioned SaaS). Returns 409 otherwise.","operationId":"addSaasGroup","parameters":[{"name":"saasId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaasEntitlementMutationBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaasEntitlementList_Output"}}}}},"summary":"Add a group to a SaaS","tags":["Saas"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/saas/{saasId}/groups/{remoteId}":{"put":{"description":"Rename an existing group. `remoteId` is the entitlement ID returned by `getSaasById`. Only allowed when the SaaS group capability is set to MANUAL (i.e. a manually-provisioned SaaS). Returns 409 otherwise.","operationId":"updateSaasGroup","parameters":[{"name":"saasId","required":true,"in":"path","schema":{"type":"string"}},{"name":"remoteId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaasEntitlementMutationBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaasEntitlementList_Output"}}}}},"summary":"Rename a group of a SaaS","tags":["Saas"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}},"delete":{"description":"Remove an existing group. `remoteId` is the entitlement ID returned by `getSaasById`. Only allowed when the SaaS group capability is set to MANUAL (i.e. a manually-provisioned SaaS). Returns 409 otherwise.","operationId":"removeSaasGroup","parameters":[{"name":"saasId","required":true,"in":"path","schema":{"type":"string"}},{"name":"remoteId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaasEntitlementList_Output"}}}}},"summary":"Remove a group from a SaaS","tags":["Saas"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/saas/{saasId}/organization-units":{"post":{"description":"Add a new organization unit to the SaaS catalog. Only allowed when the SaaS organization unit capability is set to MANUAL (i.e. a manually-provisioned SaaS). Returns 409 otherwise.","operationId":"addSaasOrganizationUnit","parameters":[{"name":"saasId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaasEntitlementMutationBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaasEntitlementList_Output"}}}}},"summary":"Add an organization unit to a SaaS","tags":["Saas"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/saas/{saasId}/organization-units/{remoteId}":{"put":{"description":"Rename an existing organization unit. `remoteId` is the entitlement ID returned by `getSaasById`. Only allowed when the SaaS organization unit capability is set to MANUAL (i.e. a manually-provisioned SaaS). Returns 409 otherwise.","operationId":"updateSaasOrganizationUnit","parameters":[{"name":"saasId","required":true,"in":"path","schema":{"type":"string"}},{"name":"remoteId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaasEntitlementMutationBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaasEntitlementList_Output"}}}}},"summary":"Rename an organization unit of a SaaS","tags":["Saas"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}},"delete":{"description":"Remove an existing organization unit. `remoteId` is the entitlement ID returned by `getSaasById`. Only allowed when the SaaS organization unit capability is set to MANUAL (i.e. a manually-provisioned SaaS). Returns 409 otherwise.","operationId":"removeSaasOrganizationUnit","parameters":[{"name":"saasId","required":true,"in":"path","schema":{"type":"string"}},{"name":"remoteId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaasEntitlementList_Output"}}}}},"summary":"Remove an organization unit from a SaaS","tags":["Saas"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/saas-application-users/{saasApplicationUserId}":{"delete":{"description":"Archive (soft-delete) a SaaS application user. The user is removed from active listings but kept for historical reporting.\n\n`saasApplicationUserId` is the identity ID returned by `getSaasById` → `identities[].id`.\n\nTo archive several identities at once, use `archiveSaasApplicationUsers` instead: it takes a list and asks for one confirmation instead of one per identity.","operationId":"archiveSaasApplicationUser","parameters":[{"name":"saasApplicationUserId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaasApplicationUserMutationResult_Output"}}}}},"summary":"Archive a SaaS application user","tags":["Saas"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/saas-application-users/{saasApplicationUserId}/permanent":{"delete":{"description":"Permanently delete a SaaS application user and its activity history. This is irreversible — prefer `archiveSaasApplicationUser` unless a hard delete is required.\n\n`saasApplicationUserId` is the identity ID returned by `getSaasById` → `identities[].id`.\n\nTo delete several identities at once, use `deleteSaasApplicationUsers` instead: it takes a list and asks for one confirmation instead of one per identity.","operationId":"deleteSaasApplicationUser","parameters":[{"name":"saasApplicationUserId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaasApplicationUserMutationResult_Output"}}}}},"summary":"Permanently delete a SaaS application user","tags":["Saas"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/saas-application-users/batch-archive":{"post":{"description":"Archive (soft-delete) MULTIPLE SaaS application users in one call — the batch form of `archiveSaasApplicationUser`, with the same rules per identity. The users are removed from active listings but kept for historical reporting.\n\nPrefer this over calling `archiveSaasApplicationUser` once per identity: cleaning up the accounts of departed employees across an application is one call here, not one call and one confirmation per account.\n\nTo gather the ids of the identities no employee owns across the company, read them from `getUnlinkedSaasIdentities` in one call instead of reading every application with `getSaasById`.\n\nArchiving or deleting an identity whose `syncedByIntegration` is true does not remove the account: the next sync of the integration brings it back. Leave those out and tell the user to remove the accounts in the application itself; Primo drops them at its next sync.\n\nWrites are independent and best-effort: the call returns 200 with a `results` manifest reporting `ok` / `error` per item — always inspect `results` rather than relying on the HTTP status to detect partial failures.","operationId":"archiveSaasApplicationUsers","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaasApplicationUsersBatchBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaasApplicationUsersBatchResult_Output"}}}}},"summary":"Archive several SaaS application users","tags":["Saas"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/saas-application-users/batch-delete":{"post":{"description":"Permanently delete MULTIPLE SaaS application users and their activity history — the batch form of `deleteSaasApplicationUser`. This is irreversible for every item that succeeds: prefer `archiveSaasApplicationUsers` unless a hard delete is required.\n\nTo gather the ids of the identities no employee owns across the company, read them from `getUnlinkedSaasIdentities` in one call instead of reading every application with `getSaasById`.\n\nArchiving or deleting an identity whose `syncedByIntegration` is true does not remove the account: the next sync of the integration brings it back. Leave those out and tell the user to remove the accounts in the application itself; Primo drops them at its next sync.\n\nWrites are independent and best-effort: the call returns 200 with a `results` manifest reporting `ok` / `error` per item — always inspect `results` rather than relying on the HTTP status to detect partial failures.","operationId":"deleteSaasApplicationUsers","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaasApplicationUsersBatchBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaasApplicationUsersBatchResult_Output"}}}}},"summary":"Permanently delete several SaaS application users","tags":["Saas"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/saas/{saasId}/identities/batch":{"post":{"description":"Record MULTIPLE accounts on a SaaS application Primo cannot provision itself — the batch form of `createSaasIdentity`, with the same rules per item. Use it to onboard a list of employees onto a manually-managed application in one call.\n\nSame constraints as the single form: only an APPROVED application whose account creation is manual, `employeeId` to attach the account to an employee or `email` alone for an account no employee owns, and re-creating a recorded account updates it and keeps its employee.\n\nWrites are independent and best-effort: the call returns 200 with a `results` manifest reporting `ok` / `error` per item — always inspect `results` rather than relying on the HTTP status to detect partial failures.","operationId":"createSaasIdentities","parameters":[{"name":"saasId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaasIdentitiesBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSaasIdentitiesResult_Output"}}}}},"summary":"Create several SaaS identities directly, with no provisioning ticket","tags":["Saas"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/catalog/countries":{"get":{"description":"Return the list of catalog country codes available to your company.","operationId":"getCatalogCountries","parameters":[{"name":"productId","required":false,"in":"query","description":"Restrict to countries where this product is available","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetCatalogCountries_Output"}}}}},"summary":"List catalog countries","tags":["Catalog"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/catalog/{countryCode}/products/search":{"post":{"description":"Search the product catalog for a given country. Filter deterministically by product type, brand, zero-touch deployment support, stock availability, and by specification via `specifications`. ram, storage (GB amounts), screenSize (whole inches), processor (`BRAND|Family`) and keyboardLayout (layout code) are canonical: pass the values the catalog filter-options endpoint returns for them, verbatim, and a value matches every product whose stored specification maps to it (`16 GB` or `Intel Core Ultra 7` match nothing). operatingSystem, resolution, position, color and the other keys are matched as case-insensitive prefixes of free text the suppliers spell inconsistently, so take those values from filter-options too. There is no numeric comparison — express \"at least 16 GB\" by listing every option at or above it. `search` only matches the product name — never put specifications in it. `total` is the full match count: page through it with page/take (take max 100) to see every match. Variants and stock are not included: read them with `getCatalogProducts`, up to 20 product ids per call.","operationId":"searchCatalogProducts","parameters":[{"name":"countryCode","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchCatalogProductsBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchCatalogProductsResult_Output"}}}}},"summary":"Search catalog products","tags":["Catalog"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/catalog/{countryCode}/filter-options":{"get":{"description":"Return every distinct filter value the catalog holds for a country, optionally narrowed to specific product types: brands plus the ram, storage, screenSize, processor, operatingSystem, resolution, position and keyboardLayout specification values. ram, storage and screenSize are canonical numbers (GB amounts, whole inches), processor is a `BRAND|Family` family and keyboardLayout a layout code; operatingSystem, resolution and position are the free-text spellings the suppliers use. Call this before searching and pass the values verbatim to the catalog product search `specifications` filter.","operationId":"getCatalogFilterOptions","parameters":[{"name":"countryCode","required":true,"in":"path","schema":{"type":"string"}},{"name":"types","required":false,"in":"query","description":"Comma-separated product types, e.g. laptop,monitor","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetCatalogFilterOptions_Output"}}}}},"summary":"Get catalog filter options","tags":["Catalog"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/catalog/{countryCode}/products/{productId}":{"get":{"description":"Return the full details of a catalog product for a country, including its variants and per-supplier stock information. To read several products of the same country, use `getCatalogProducts` (up to 20 per call) instead of calling this once per product.","operationId":"getCatalogProduct","parameters":[{"name":"countryCode","required":true,"in":"path","schema":{"type":"string"}},{"name":"productId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetCatalogProduct_Output"}}}}},"summary":"Get a catalog product","tags":["Catalog"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/catalog/{countryCode}/products/by-ids":{"post":{"description":"Return the full details of up to 20 catalog products for a country in one call, in the order requested, each with its variants and per-supplier stock in that country. Use it after `searchCatalogProducts` to compare products, instead of calling `getCatalogProduct` once per product. One call per country: prices and stock depend on it. A product with no variant in the country comes back with an empty `variants` list and a discontinued one with `isDiscontinued`; ids that match no product are listed in `notFound`.","operationId":"getCatalogProducts","parameters":[{"name":"countryCode","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetCatalogProductsBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetCatalogProducts_Output"}}}}},"summary":"Get several catalog products","tags":["Catalog"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/shipping-countries":{"get":{"description":"Return your company's shipping countries with their enablement status.","operationId":"getShippingCountries","parameters":[],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetShippingCountries_Output"}}}}},"summary":"List shipping countries","tags":["Catalog"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/shipping-countries/{countryCode}/addresses":{"get":{"description":"Return the company's saved addresses in the given shipping country. Use one of these as the shipping address when creating an order.","operationId":"getCompanyAddresses","parameters":[{"name":"countryCode","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetCompanyAddresses_Output"}}}}},"summary":"List company addresses for a shipping country","tags":["Catalog"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/catalog/{countryCode}/favorites":{"get":{"description":"Return the products an admin has pinned as favorites for one country, split into devices and accessories and carrying the full product details — the same shape searchCatalogProducts returns. Favorites lead the catalog listing in the cockpit and are curated by hand, so this is the deterministic answer to \"what do we recommend here\"; the equipment policy (getEquipmentPolicyResult) is the AI-computed one. Products no longer sold in that country are omitted.","operationId":"listCatalogFavorites","parameters":[{"name":"countryCode","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CatalogFavorites_Output"}}}}},"summary":"List the catalog favorites of a country","tags":["Catalog"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/catalog/{countryCode}/products/{productId}/favorite":{"put":{"description":"Mark one catalog product as a favorite for one country, so it leads the catalog listing for everyone in the company. Idempotent — pinning an already-favorite product changes nothing. Answers with the refreshed favorites of that country. Fails with 404 when the product is not sold in that country; call searchCatalogProducts for the same country first to get a valid product id. To remove one, use removeCatalogFavorite.","operationId":"addCatalogFavorite","parameters":[{"name":"countryCode","required":true,"in":"path","schema":{"type":"string"}},{"name":"productId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CatalogFavorites_Output"}}}}},"summary":"Pin a catalog product as a favorite","tags":["Catalog"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}},"delete":{"description":"Remove one catalog product from the favorites of one country, so it stops leading the catalog listing. Idempotent — unpinning a product that is not a favorite changes nothing and still answers with the refreshed favorites of that country. This affects what the whole company sees in the catalog, so confirm with the user before calling it. To pin one, use addCatalogFavorite.","operationId":"removeCatalogFavorite","parameters":[{"name":"countryCode","required":true,"in":"path","schema":{"type":"string"}},{"name":"productId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CatalogFavorites_Output"}}}}},"summary":"Unpin a catalog product from the favorites","tags":["Catalog"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/shipments":{"get":{"description":"Return the list of shipments for your company, most recent first. Pass `employeeId` to read the shipments of one person instead of paging through the company. Only an offboarding shipment carries an employee, so every other shipment is then left out. Resolve a name to an id with `getEmployees` first — never enumerate the company to find one shipment.","operationId":"getShipments","parameters":[{"name":"page","required":false,"in":"query","description":"Page number","schema":{"minimum":1,"maximum":9007199254740991,"default":1,"type":"number"}},{"name":"perPage","required":false,"in":"query","description":"Number of items per page (max 100)","schema":{"minimum":1,"maximum":100,"default":50,"type":"number"}},{"name":"employeeId","required":false,"in":"query","description":"Return only the shipments attached to this employee. Only an offboarding shipment carries one, so every other shipment of the company is excluded.","schema":{"pattern":"^[a-f\\d]{24}$","type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetShipments_Output"}}}}},"summary":"Get shipments, optionally narrowed to one employee","tags":["Shipments"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}},"post":{"description":"Create a new shipment for your company.\n\nProvide sender and recipient addresses, parcel dimensions, content list, and billing profile.","operationId":"createShipment","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateShipmentBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShipmentWriteResult_Output"}}}}},"summary":"Create a shipment","tags":["Shipments"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/shipments/{shipmentId}":{"get":{"description":"Return the shipment details for the given shipment ID.","operationId":"getShipment","parameters":[{"name":"shipmentId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetShipment_Output"}}}}},"summary":"Get a shipment by ID","tags":["Shipments"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/knowledge-base-items":{"get":{"description":"List every knowledge base item (e.g. Skills — reusable instruction packages) owned by the company, with their draft, published text and publication status. Call this to find an item's id before reading, editing or publishing it. Does not include the Equipment or Purchasing policy — use their dedicated endpoints instead.","operationId":"listKnowledgeBaseItems","parameters":[],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListKnowledgeBaseItemsResponseDto_Output"}}}}},"summary":"List the company knowledge base items","tags":["KnowledgeBaseItems"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/knowledge-base-items/{id}":{"get":{"description":"Return a single knowledge base item by id: its editable draft, the published text the agent sees at runtime (or null if never published), and its publication status. Read this before updating so you can show the user the current text.","operationId":"getKnowledgeBaseItem","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetKnowledgeBaseItemResponseDto_Output"}}}}},"summary":"Get a knowledge base item","tags":["KnowledgeBaseItems"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/onboardings":{"get":{"description":"Return the list of employee onboardings for your company.","operationId":"getOnboardings","parameters":[{"name":"page","required":false,"in":"query","description":"Page number","schema":{"minimum":1,"maximum":9007199254740991,"default":1,"type":"number"}},{"name":"perPage","required":false,"in":"query","description":"Number of items per page (max 100)","schema":{"minimum":1,"maximum":100,"default":50,"type":"number"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetOnboardings_Output"}}}}},"summary":"Get all onboardings","tags":["Onboardings"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}},"post":{"description":"Start the onboarding of an employee who already exists in Primo: creates the onboarding, its ticket and the \"Confirm onboarding information\" task, then the admins run the email, SaaS provisioning and equipment steps from the cockpit according to the onboarding settings. The employee must exist first — `createEmployee` only creates the record and never starts an onboarding, so call it, then this operation with the returned id. Refused when the employee already has an open onboarding (`ONBOARDING_ALREADY_EXISTS`), is synchronised from a connected HRIS (`EMPLOYEE_MANAGED_BY_HRIS` — that HRIS drives their onboarding), is hidden or has already left, when no start date is known (send `startDate` or set it on the employee first), or when onboarding tickets are not enabled for the company. A start date in the past is accepted for a joiner already in post. To act on an onboarding that already exists, use `getOnboardings`, `completeOnboarding`, `ignoreOnboarding` or `executeOnboardingEquipment` instead.","operationId":"createOnboarding","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOnboardingBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetOnboarding_Output"}}}}},"summary":"Create an onboarding for an existing employee","tags":["Onboardings"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/onboarding-settings":{"get":{"description":"Return the company onboarding settings: which steps (email, SaaS provisioning, equipment) every onboarding includes, who owns each of them and when they are due, the scheduling of each step, the default ticket owner, priority and subscribers, whether the Primo AI agent is put on onboarding tickets or drives the equipment step, and when a hire detected in the HRIS gets its onboarding ticket. These settings shape every onboarding created afterwards, not the ones already open. Read this before updateOnboardingSettings so you can report what changes. For the settings of one onboarding already in flight, use getOnboarding instead.","operationId":"getOnboardingSettings","parameters":[],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetOnboardingSettings_Output"}}}}},"summary":"Get the onboarding settings","tags":["Onboardings"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}},"patch":{"description":"Change the company onboarding settings — the steps every onboarding includes, their owners, due dates and scheduling, the default ticket owner, priority and subscribers, the Primo AI agent options, and when a hire detected in the HRIS gets its onboarding ticket (`onboardingTicketCreation`). Only the fields you send are changed; everything else keeps its stored value, so send just what the user asked to change rather than the whole object. `defaultTaskOwner`, `owner` and `defaultTaskSubscribers` take a Primo employee id (type EMPLOYEE) or the Clerk user id of an admin with no employee record (type EXTERNAL_ADMIN) — look the person up with getEmployees first; a person who does not belong to the company is refused. Sending null clears a field. The new settings apply to onboardings created afterwards, never to the ones already open. Call getOnboardingSettings first so you can tell the user what the change replaces.","operationId":"updateOnboardingSettings","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateOnboardingSettingsBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetOnboardingSettings_Output"}}}}},"summary":"Update the onboarding settings","tags":["Onboardings"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/onboardings/{onboardingId}":{"get":{"description":"Return the onboarding details for the given onboarding ID. `stepProgress` counts its steps through out of all of them: on `ACTIONS` its steps done, scheduled or skipped; otherwise the typed tasks of its ticket completed or cancelled (read them with `getTicket`).","operationId":"getOnboarding","parameters":[{"name":"onboardingId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetOnboarding_Output"}}}}},"summary":"Get an onboarding by ID","tags":["Onboardings"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/onboardings/complete":{"post":{"description":"Close many onboardings for employees already in post in one call. Each one creates the employee from the connected HRIS data if needed and marks the employee active, without executing the remaining onboarding actions (no equipment ordered, no SaaS provisioned). Best-effort and independent: the call returns 200 with a per-id `results` manifest (`ok` / `error`) — always inspect `results` rather than the HTTP status to detect partial failures. Up to 10 ids per call.","operationId":"completeOnboardings","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompleteOnboardingsBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompleteOnboardingsResult_Output"}}}}},"summary":"Complete onboardings in bulk","tags":["Onboardings"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/onboardings/{onboardingId}/complete":{"post":{"description":"Close an onboarding for an employee already in post: creates the employee from the connected HRIS data if needed and marks the employee active, without executing the remaining onboarding actions (no equipment ordered, no SaaS provisioned).","operationId":"completeOnboarding","parameters":[{"name":"onboardingId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetOnboarding_Output"}}}}},"summary":"Complete an onboarding","tags":["Onboardings"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/onboardings/ignore":{"post":{"description":"Discard many pending onboardings in one call — cancels each without creating the employee. Best-effort and independent: the call returns 200 with a per-id `results` manifest (`ok` / `error`) — always inspect `results` rather than the HTTP status to detect partial failures. Up to 10 ids per call.","operationId":"ignoreOnboardings","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IgnoreOnboardingsBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IgnoreOnboardingsResult_Output"}}}}},"summary":"Ignore onboardings in bulk","tags":["Onboardings"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/onboardings/{onboardingId}/ignore":{"post":{"description":"Discard a pending onboarding: cancels it without creating the employee (the opposite of completeOnboarding, which keeps the employee active). Only pending onboardings can be ignored.","operationId":"ignoreOnboarding","parameters":[{"name":"onboardingId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetOnboarding_Output"}}}}},"summary":"Ignore an onboarding","tags":["Onboardings"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/onboardings/{onboardingId}/equipment":{"post":{"description":"Equip a joiner and close the Equipment step of their onboarding in one call: places the catalog order when `order` is provided, assigns devices and accessories from existing stock when `assignedFromInventory` is provided, then moves the step and its onboarding-ticket task to done and links the order to the ticket. Send neither when the joiner is already equipped — the step still closes. Returns the onboarding and the order placed, or `order: null` when nothing was purchased. This is the only way to close an onboarding Equipment step: `updateTaskStatus` refuses that task, and `createOrder` places an order without touching the onboarding. For an EQUIPMENT_ORDER task on a ticket, use `executeEquipmentOrderIntent` instead, and for an EMPLOYEE_CREATION task `executeEmployeeCreationIntent`: a typed task completes only through its intent. To buy for stock or outside an onboarding, use `createOrder` instead. To close a whole onboarding for someone already in post without ordering or provisioning anything, use `completeOnboarding` instead. Refused with `ONBOARDING_EQUIPMENT_ALREADY_EXECUTED` when the step is already done — that means the work happened, not that the call failed.","operationId":"executeOnboardingEquipment","parameters":[{"name":"onboardingId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExecuteOnboardingEquipmentBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExecuteOnboardingEquipmentResult_Output"}}}}},"summary":"Execute the equipment step of an onboarding","tags":["Onboardings"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/email-account-intents":{"post":{"description":"Ask for an employee's professional mailbox at the company's email provider as a task a ticket tracks. Creates the intent and its EMAIL_ACCOUNT task. Without `scheduleDate` the mailbox is created right away; with one, the task sleeps until that date and the mailbox is created when it wakes up — nobody has to execute it. Pass the onboarding ticket as `parentTicketId`; without one Primo opens a ticket for the employee to hold the task. `createTicket` and `createTask` cannot make a typed task. The mailbox is created at the employee's email as it stands when the task runs: set or fix that address on the employee (`updateEmployee`), not here. Returns the intent `id`, its `taskId` and the `ticketId` holding it. The task cannot be marked done by hand; it completes when the mailbox exists. Take the groups, roles, licenses and organization units from `getSaasById` of the email provider (the SaaS with `isEmailProvider` in `getSaas`). For an onboarding still on the classic email step, the step is handled by the onboarding itself; this intent is the email work tracked as a task on a ticket (an EMAIL_ACCOUNT task), and never closes an onboarding email step. Refused with `EMAIL_PROVIDER_NOT_FOUND` (no connected email provider), `COMPANY_SAAS_APPLICATION_NOT_CAPABLE` (the provider does not create users automatically), `EMPLOYEE_NOT_FOUND`, `PARENT_TICKET_IS_TYPED` or `PARENT_TICKET_IS_A_TASK` (pass the untyped ticket instead), `PARENT_TICKET_NOT_FOUND`.","operationId":"createEmailAccountIntent","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEmailAccountIntentBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailAccountIntent_Output"}}}}},"summary":"Create an email account intent","tags":["Onboardings"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/email-account-intents/{intentId}":{"patch":{"description":"Change the credentials recipient, the personal email or the groups, roles, licenses and organization units of an email account intent before its mailbox is created — typically while its task sleeps until its date. Only the fields you send change; a resource list is replaced whole. The employee cannot change: create a new intent for someone else. Refused with `INTENT_ALREADY_EXECUTED` once the mailbox exists, `EXECUTION_IN_PROGRESS` while it is being created, `TICKET_CLOSED` when its task is completed or cancelled. For an onboarding still on the classic email step, the step is handled by the onboarding itself; this intent is the email work tracked as a task on a ticket (an EMAIL_ACCOUNT task), and never closes an onboarding email step.","operationId":"updateEmailAccountIntent","parameters":[{"name":"intentId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateEmailAccountIntentBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailAccountIntent_Output"}}}}},"summary":"Update an email account intent","tags":["Onboardings"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/email-account-intents/{intentId}/execute":{"post":{"description":"Create the intent's mailbox at the email provider now, link the mailbox to its task and to the ticket holding it, and complete the task. Rarely needed: the mailbox is created on its own when the task is created without a date or wakes up on its date. Use it to retry after a refusal left the task PENDING with a comment. This is the only way to complete an EMAIL_ACCOUNT task: `updateTaskStatus` refuses it with `TaskLockedByTypeError` naming this operation. Safe to retry: an intent executed earlier answers `outcome: ALREADY_EXECUTED` and creates nothing again. Refused with `TICKET_SCHEDULED` before a scheduled task wakes up, `TICKET_CLOSED`, `EXECUTION_IN_PROGRESS`, `EMAIL_ACCOUNT_ALREADY_EXISTS` (the employee already has an account at an address other than their email), `EMAIL_ACCOUNT_NOT_CREATED` (the provider refused), `COMPANY_SAAS_APPLICATION_NOT_CAPABLE`; a refusal leaves the task PENDING with an internal comment on the ticket. For an onboarding still on the classic email step, the step is handled by the onboarding itself; this intent is the email work tracked as a task on a ticket (an EMAIL_ACCOUNT task), and never closes an onboarding email step.","operationId":"executeEmailAccountIntent","parameters":[{"name":"intentId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExecuteEmailAccountIntentResult_Output"}}}}},"summary":"Execute an email account intent","tags":["Onboardings"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/employee-creation-intents":{"post":{"description":"Create the employee of an onboarding as a task the ticket tracks, from the HR information (name, emails, phone, start date, job, legal entity, work location, teams, manager, address). Creates the intent and its EMPLOYEE_CREATION task. Without `scheduleDate` the employee is created right away — a real employee and Clerk user, so confirm the information first; with one, the task sleeps until that date and the employee is created when it wakes up — nobody has to execute it. A field you leave out is read from the onboarding: its HRIS record, or what the admin wrote on a manual onboarding (`hire` in `getOnboarding`), so send only what differs from it; null clears a field. Read the returned intent to see what was filled in. Pass the ticket the task belongs to as `parentTicketId`; without one Primo opens a ticket for it. `createTicket` and `createTask` cannot make a typed task. Returns the intent `id`, its `taskId` and the `ticketId` holding it. When the employee cannot be created (for instance `EMPLOYEE_INFORMATION_INCOMPLETE`), the task stays PENDING with an internal comment: fix the intent with `updateEmployeeCreationIntent`, then `executeEmployeeCreationIntent`. The task cannot be marked done by hand: `updateTaskStatus` refuses it, and it completes once Primo has created the employee. `createEmployee` only creates a record with no onboarding or task, and `completeOnboarding` closes the whole onboarding without this task; use the employee creation intent for an EMPLOYEE_CREATION task a ticket tracks. Refused with `ONBOARDING_NOT_FOUND`, `ONBOARDING_HAS_EMPLOYEE_CREATION` (the onboarding already has a live one, whose id comes back as `intentId`: update or execute it), `MANAGER_NOT_FOUND`, `PARENT_TICKET_IS_TYPED` or `PARENT_TICKET_IS_A_TASK` (pass the untyped ticket instead), `PARENT_TICKET_NOT_FOUND`.","operationId":"createEmployeeCreationIntent","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEmployeeCreationIntentBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmployeeCreationIntent_Output"}}}}},"summary":"Create an employee creation intent","tags":["Onboardings"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/employee-creation-intents/{intentId}":{"patch":{"description":"Change the HR information an employee creation intent will create the employee from, before it executes — typically while its task sleeps until its date, or after a refusal left it PENDING. Only the fields you send change (`teams` is replaced whole); null clears one. The onboarding cannot change: create a new intent for another onboarding. Refused with `INTENT_NOT_FOUND`, `INTENT_ALREADY_EXECUTED` once executed, `TICKET_CLOSED` when its task is completed or cancelled, `MANAGER_NOT_FOUND`. The task cannot be marked done by hand: `updateTaskStatus` refuses it, and it completes once Primo has created the employee. `createEmployee` only creates a record with no onboarding or task, and `completeOnboarding` closes the whole onboarding without this task; use the employee creation intent for an EMPLOYEE_CREATION task a ticket tracks.","operationId":"updateEmployeeCreationIntent","parameters":[{"name":"intentId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateEmployeeCreationIntentBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmployeeCreationIntent_Output"}}}}},"summary":"Update an employee creation intent","tags":["Onboardings"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/employee-creation-intents/{intentId}/execute":{"post":{"description":"Carry out an employee creation intent: creates the employee (or updates the one the onboarding already holds) from the intent, links them to the onboarding, cancels a leftover offboarding, adds them to the company in Clerk — a real user account — links the employee to its task and to the ticket holding it, and completes the task. Rarely needed: the employee is created on its own when the task is created without a date or wakes up on its date. Use it to retry after a refusal left the task PENDING with a comment. This is the only way to complete an EMPLOYEE_CREATION task by hand: `updateTaskStatus` refuses it with `TaskLockedByTypeError` naming this operation. Safe to retry: an intent executed earlier answers `outcome: ALREADY_EXECUTED` and creates nothing again. Refused with `EMPLOYEE_INFORMATION_INCOMPLETE` (first name, last name, work email and start date are all required: fix them with `updateEmployeeCreationIntent`), `TICKET_SCHEDULED` before a scheduled task wakes up, `TICKET_CLOSED`, `EXECUTION_IN_PROGRESS`, `INVALID_EMAIL`, `FAIL_TO_CREATE_OR_UPDATE_EMPLOYEE`; a refusal leaves the task PENDING with an internal comment on the ticket. `completeOnboarding` closes a whole onboarding without this task; use this operation for an EMPLOYEE_CREATION task.","operationId":"executeEmployeeCreationIntent","parameters":[{"name":"intentId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExecuteEmployeeCreationIntentResult_Output"}}}}},"summary":"Execute an employee creation intent","tags":["Onboardings"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/saas-selection-intents/{intentId}":{"get":{"description":"Return the intent behind the \"Configure SaaS provisioning\" task (type SAAS_SELECTION) of an onboarding ticket: the applications proposed for the employee as `proposedApps` — each with its `saasId`, groups, roles, licenses, organization units and credentials recipient — and `executedAt` once validated. Take the `intentId` from the task (`getTicket` or `getTasks`). `proposedApps` has the shape `executeSaasSelectionIntent` takes as `apps`: read it, adjust it, send it there to validate the selection. Refused with `INTENT_NOT_FOUND`.","operationId":"getSaasSelectionIntent","parameters":[{"name":"intentId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaasSelectionIntent_Output"}}}}},"summary":"Get a SaaS selection intent","tags":["Onboardings"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/saas-selection-intents/{intentId}/execute":{"post":{"description":"Validate the SaaS selection of an onboarding: opens one SAAS_PROVISIONING task per app in `apps` under the onboarding ticket, started now or SCHEDULED until `scheduleDate`, then completes the \"Configure SaaS provisioning\" task (type SAAS_SELECTION). This is the only way to complete a SAAS_SELECTION task: `updateTaskStatus` refuses it with `TaskLockedByTypeError` naming this operation. Start `apps` from `proposedApps` of `getSaasSelectionIntent`, taking each `saasId` from there or from `getSaas`: a `saasId` that is not a SaaS of the company, an app the onboarding ticket already has an account task for, the email provider and an app that creates its accounts at first login get no task, without a refusal; an empty `apps` opens none. To add one app to an onboarding without this task, use `createSaasProvisioningIntent`. Safe to retry: a selection validated earlier answers `outcome: ALREADY_EXECUTED` and opens nothing again. A `personalEmail` another employee already holds is not saved. Refused with `INVALID_SAAS_SELECTION` (a `saasId` that is not an id, or a recipient without an email), `TICKET_CLOSED` (the task was cancelled), `EXECUTION_IN_PROGRESS`, `INTENT_NOT_FOUND`.","operationId":"executeSaasSelectionIntent","parameters":[{"name":"intentId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExecuteSaasSelectionIntentBody"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExecuteSaasSelectionIntentResult_Output"}}}}},"summary":"Execute a SaaS selection intent","tags":["Onboardings"],"x-primo-access-level":"write","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Write","className":"badge-write","color":"#B42318"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-write\">Key: Write</span><span className=\"badge-company\">Scope: Company</span>"}}},"/offboardings":{"get":{"description":"Return the list of employee offboardings for your company.","operationId":"getOffboardings","parameters":[{"name":"page","required":false,"in":"query","description":"Page number","schema":{"minimum":1,"maximum":9007199254740991,"default":1,"type":"number"}},{"name":"perPage","required":false,"in":"query","description":"Number of items per page (max 100)","schema":{"minimum":1,"maximum":100,"default":50,"type":"number"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetOffboardings_Output"}}}}},"summary":"Get all offboardings","tags":["Offboardings"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}},"/offboardings/{offboardingId}":{"get":{"description":"Return the offboarding details for the given offboarding ID.","operationId":"getOffboarding","parameters":[{"name":"offboardingId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetOffboarding_Output"}}}}},"summary":"Get an offboarding by ID","tags":["Offboardings"],"x-primo-access-level":"read","x-primo-access-scope":["company"],"x-badges":[{"name":"Key: Read","className":"badge-read","color":"#0F766E"},{"name":"Scope: Company","className":"badge-company","color":"#0284C7"}],"x-mint":{"content":"<span className=\"badge-read\">Key: Read</span><span className=\"badge-company\">Scope: Company</span>"}}}},"info":{"title":"Public API - BETA","description":"Read docs on https://docs.getprimo.com/","version":"1.0","contact":{}},"tags":[],"servers":[{"url":"https://api.getprimo.com"}],"components":{"securitySchemes":{"apikey":{"scheme":"bearer","bearerFormat":"API key","type":"http","description":"Use your Primo API key in the Authorization header as `Bearer <API_KEY>`."}},"schemas":{"GetAdmins_Output":{"type":"object","properties":{"data":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"type":{"type":"string","const":"employee"},"id":{"type":"string"},"email":{"type":"string"},"roleName":{"type":"string"}},"required":["type","id","email","roleName"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"external"},"userId":{"type":"string"},"email":{"type":"string"},"roleName":{"type":"string"}},"required":["type","userId","email","roleName"],"additionalProperties":false}]}}},"required":["data"],"additionalProperties":false},"SendEmailToAdminsBody":{"type":"object","properties":{"subject":{"description":"Subject line of the email","type":"string","minLength":1,"maxLength":200},"body":{"description":"Body of the email, text or HTML (never markdown). It is sanitized and inserted into the Primo email template, which already provides the header and footer.","type":"string","minLength":1,"maxLength":100000},"adminIds":{"description":"Admins to email, as returned by getAdmins (an employee `id` or an external `userId`). Omit to email every admin.","minItems":1,"type":"array","items":{"type":"string","minLength":1}}},"required":["subject","body"]},"SendEmailToAdmins_Output":{"type":"object","properties":{"recipientCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["recipientCount"],"additionalProperties":false},"GetMyCompany_Output":{"type":"object","properties":{"id":{"type":"string","description":"Unique company identifier"},"name":{"type":"string","description":"Company display name"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","name","createdAt","updatedAt"],"additionalProperties":false},"GetCompanyMetrics_Output":{"type":"object","properties":{"report":{"type":"object","description":"Headline counts of the company with the cockpit table behind each of them. A count equal to 0, or that the caller has no permission to read, is left out","properties":{"devicesInUseAssignedCount":{"description":"Devices in use that are assigned to an employee","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"devicesInUseAssignedURL":{"description":"Cockpit table of the devices in use that are assigned to an employee","type":"string"},"devicesInUseUnassignedCount":{"description":"Devices in use that are not assigned to an employee","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"devicesInUseUnassignedURL":{"description":"Cockpit table of the devices in use that are not assigned to an employee","type":"string"},"devicesInStockCount":{"description":"Devices in stock","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"devicesInStockURL":{"description":"Cockpit table of the devices in stock","type":"string"},"employeesCount":{"description":"Current employees","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"employeesToEnrollCount":{"description":"Employees who still have to enroll in MDM","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"employeesToEnrollURL":{"description":"Cockpit table of the employees who still have to enroll in MDM","type":"string"},"employeesEnrolledCount":{"description":"Employees enrolled in MDM","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"employeesEnrolledURL":{"description":"Cockpit table of the employees enrolled in MDM","type":"string"},"employeesToOnboardOrOffboardCount":{"description":"Employees to onboard or to offboard","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"employeesToOnboardCount":{"description":"Employees to onboard","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"employeesToOnboardThisWeekCount":{"description":"Employees to onboard this week","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"employeesToOnboardURL":{"description":"Cockpit table of the pending onboardings","type":"string"},"employeesToOffboardCount":{"description":"Employees to offboard","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"employeesToOffboardThisWeekCount":{"description":"Employees to offboard this week","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"employeesToOffboardURL":{"description":"Cockpit table of the pending offboardings","type":"string"},"devicesWithMDMOnCount":{"description":"Devices in use with MDM on","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"devicesWithMDMOnURL":{"description":"Cockpit table of the devices in use with MDM on","type":"string"},"devicesWithMDMOnInAnotherMDMCount":{"description":"Devices in use enrolled in another MDM","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"devicesWithMDMOnInAnotherMDMURL":{"description":"Cockpit table of the devices in use enrolled in another MDM","type":"string"},"devicesWithMDMOffCount":{"description":"Devices in use with MDM off","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"devicesWithMDMOffURL":{"description":"Cockpit table of the devices in use with MDM off","type":"string"},"devicesWithMissingAgentCount":{"description":"Devices in use whose MDM agent is missing","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"devicesWithMissingAgentURL":{"description":"Cockpit table of the devices in use whose MDM agent is missing","type":"string"},"devicesWithReadyZTDCount":{"description":"Devices in use ready for zero-touch deployment","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"devicesWithReadyZTDURL":{"description":"Cockpit table of the devices in use ready for zero-touch deployment","type":"string"},"devicesCompliantCount":{"description":"Devices with no compliance issue","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"devicesWithIssuesCount":{"description":"Devices with at least one compliance issue","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"devicesNotEncryptedCount":{"description":"Devices in use whose disk is not encrypted","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"devicesNotEncryptedURL":{"description":"Cockpit table of the devices in use whose disk is not encrypted","type":"string"},"devicesWithoutRecoveryKeyCount":{"description":"Devices in use with no disk recovery key escrowed","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"devicesWithoutRecoveryKeyURL":{"description":"Cockpit table of the devices in use with no disk recovery key escrowed","type":"string"},"devicesWithIcloudLockIssueCount":{"description":"Devices in use with an iCloud lock issue","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"devicesWithIcloudLockIssueURL":{"description":"Cockpit table of the devices in use with an iCloud lock issue","type":"string"},"edrEnabled":{"description":"Whether the company has an EDR (endpoint detection and response) connected","type":"boolean"},"devicesWithActiveEDRCount":{"description":"Devices in use with an active EDR","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"devicesWithActiveEDRURL":{"description":"Cockpit table of the devices in use with an active EDR","type":"string"},"devicesWithEdrNotDetectedCount":{"description":"Devices in use where the EDR is not detected","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"devicesWithEdrNotDetectedURL":{"description":"Cockpit table of the devices in use where the EDR is not detected","type":"string"},"devicesWithEdrActivationIssueCount":{"description":"Devices in use with an EDR activation issue","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"devicesWithEdrActivationIssueURL":{"description":"Cockpit table of the devices in use with an EDR activation issue","type":"string"},"devicesWithEdrInactiveCount":{"description":"Devices in use whose EDR has been inactive for 7 days","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"devicesWithEdrInactiveURL":{"description":"Cockpit table of the devices in use whose EDR has been inactive for 7 days","type":"string"},"devicesOnlineCount":{"description":"Devices in use that are online","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"devicesOnlineURL":{"description":"Cockpit table of the devices in use that are online","type":"string"},"devicesOfflineCount":{"description":"Devices in use that are offline","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"devicesOfflineURL":{"description":"Cockpit table of the devices in use that are offline","type":"string"},"devicesOffline7dCount":{"description":"Devices in use that have been offline for 7 days","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"devicesOffline7dURL":{"description":"Cockpit table of the devices in use that have been offline for 7 days","type":"string"}},"required":["devicesInUseAssignedURL","devicesInUseUnassignedURL","devicesInStockURL","employeesToEnrollURL","employeesEnrolledURL","employeesToOnboardURL","employeesToOffboardURL","devicesWithMDMOnURL","devicesWithMDMOnInAnotherMDMURL","devicesWithMDMOffURL","devicesWithMissingAgentURL","devicesWithReadyZTDURL","devicesNotEncryptedURL","devicesWithoutRecoveryKeyURL","devicesWithIcloudLockIssueURL","devicesWithActiveEDRURL","devicesWithEdrNotDetectedURL","devicesWithEdrActivationIssueURL","devicesWithEdrInactiveURL","devicesOnlineURL","devicesOfflineURL","devicesOffline7dURL"],"additionalProperties":false},"companyMetrics":{"type":"object","description":"Every raw counter the report is built from, zeros included. A counter the caller has no permission to read is null","properties":{"id":{"description":"Company identifier","type":"string"},"countConnectedApps":{"anyOf":[{"description":"SaaS applications connected through their API","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"countCurrentEmployees":{"anyOf":[{"description":"Current employees","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"deviceMdm":{"anyOf":[{"type":"object","properties":{"countMdmOn":{"description":"Devices with MDM on","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"countMdmOff":{"description":"Devices with MDM off","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"countMdmOnInAnotherMdm":{"description":"Devices enrolled in another MDM","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"countMissingAgent":{"description":"Devices whose MDM agent is missing","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"countReadyZTD":{"description":"Devices ready for zero-touch deployment","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["countMdmOn","countMdmOff","countMdmOnInAnotherMdm","countMissingAgent","countReadyZTD"],"additionalProperties":false},{"type":"null"}]},"deviceEdr":{"anyOf":[{"type":"object","properties":{"countNotDetected":{"description":"Devices where the EDR is not detected","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"countInstallIncomplete":{"description":"Devices where the EDR installation is incomplete","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"countActivationIssues":{"description":"Devices with an EDR activation issue","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"countOfflineFor7Days":{"description":"Devices whose EDR has been inactive for 7 days","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"countActive":{"description":"Devices with an active EDR","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["countNotDetected","countInstallIncomplete","countActivationIssues","countOfflineFor7Days","countActive"],"additionalProperties":false},{"type":"null"}]},"deviceCompliance":{"anyOf":[{"type":"object","properties":{"countCompliant":{"description":"Devices with no compliance issue","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"countIssuesExist":{"description":"Devices with at least one compliance issue","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"countCompliantByAlertCount":{"description":"Devices with no compliance issue, counted from the device alert count","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"countIssuesExistByAlertCount":{"description":"Devices with at least one compliance issue, counted from the device alert count","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["countCompliant","countIssuesExist","countCompliantByAlertCount","countIssuesExistByAlertCount"],"additionalProperties":false},{"type":"null"}]},"deviceComplianceDetails":{"anyOf":[{"type":"object","properties":{"countToEncrypt":{"description":"Devices whose disk is not encrypted","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"countWithoutRecoveryKey":{"description":"Devices with no disk recovery key escrowed","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"countWithIcloudLockIssue":{"description":"Devices with an iCloud lock issue","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["countToEncrypt","countWithoutRecoveryKey","countWithIcloudLockIssue"],"additionalProperties":false},{"type":"null"}]},"employeeEnrollment":{"anyOf":[{"type":"object","properties":{"countToEnroll":{"description":"Employees who still have to enroll in MDM","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"countEnrolled":{"description":"Employees enrolled in MDM","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["countToEnroll","countEnrolled"],"additionalProperties":false},{"type":"null"}]},"deviceAssignment":{"anyOf":[{"type":"object","properties":{"countInUseAssigned":{"description":"Devices in use that are assigned to an employee","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"countInUseUnassigned":{"description":"Devices in use that are not assigned to an employee","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"countInStock":{"description":"Devices in stock","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["countInUseAssigned","countInUseUnassigned","countInStock"],"additionalProperties":false},{"type":"null"}]},"deviceOnline":{"anyOf":[{"type":"object","properties":{"countOnline":{"description":"Devices that are online","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"countOffline":{"description":"Devices that are offline","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"countOfflineFor7Days":{"description":"Devices that have been offline for 7 days","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["countOnline","countOffline","countOfflineFor7Days"],"additionalProperties":false},{"type":"null"}]},"identitiesAndAccess":{"anyOf":[{"type":"object","properties":{"countAssignedToEmployee":{"description":"SaaS identities assigned to an employee","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"countAssignedToMachine":{"description":"SaaS identities assigned to a machine","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"countAssignedToGroup":{"description":"SaaS identities assigned to a group","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"countAssignedToGuest":{"description":"SaaS identities assigned to a guest","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"countAssignedToContractor":{"description":"SaaS identities assigned to a contractor","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"countToLink":{"description":"SaaS identities still to link to an employee","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["countAssignedToEmployee","countAssignedToMachine","countAssignedToGroup","countAssignedToGuest","countAssignedToContractor","countToLink"],"additionalProperties":false},{"type":"null"}]}},"required":["id","countConnectedApps","countCurrentEmployees","deviceMdm","deviceEdr","deviceCompliance","deviceComplianceDetails","employeeEnrollment","deviceAssignment","deviceOnline","identitiesAndAccess"],"additionalProperties":false}},"required":["report","companyMetrics"],"additionalProperties":false},"ListCustomFieldsResponse_Output":{"type":"object","properties":{"total":{"type":"integer","minimum":0,"maximum":9007199254740991},"list":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"companyId":{"type":"string"},"label":{"type":"string"},"fieldType":{"type":"string","enum":["SELECT","MULTI_SELECT","CHECKBOX","TEXT","DATE","NUMBER","URL","IMAGE"]},"applyTo":{"type":"array","items":{"type":"string","enum":["DEVICE","ACCESSORY","EMPLOYEE","ORDER"]}},"status":{"type":"string","enum":["ACTIVE","ARCHIVED"]},"options":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"value":{"type":"string"}},"required":["id","value"],"additionalProperties":false}},"aiInstruction":{"description":"Free-text instruction telling the AI how to fill this field and what it means. Null when unset.","anyOf":[{"type":"string"},{"type":"null"}]},"aiFillEnabled":{"description":"Whether the AI auto-fills this field. Requires a non-empty aiInstruction.","type":"boolean"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","companyId","label","fieldType","applyTo","status","options","aiInstruction","aiFillEnabled","createdAt","updatedAt"],"additionalProperties":false}}},"required":["total","list"],"additionalProperties":false},"CustomFieldResponse_Output":{"type":"object","properties":{"id":{"type":"string"},"companyId":{"type":"string"},"label":{"type":"string"},"fieldType":{"type":"string","enum":["SELECT","MULTI_SELECT","CHECKBOX","TEXT","DATE","NUMBER","URL","IMAGE"]},"applyTo":{"type":"array","items":{"type":"string","enum":["DEVICE","ACCESSORY","EMPLOYEE","ORDER"]}},"status":{"type":"string","enum":["ACTIVE","ARCHIVED"]},"options":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"value":{"type":"string"}},"required":["id","value"],"additionalProperties":false}},"aiInstruction":{"description":"Free-text instruction telling the AI how to fill this field and what it means. Null when unset.","anyOf":[{"type":"string"},{"type":"null"}]},"aiFillEnabled":{"type":"boolean","description":"Whether the AI auto-fills this field. Requires a non-empty aiInstruction."},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","companyId","label","fieldType","applyTo","status","options","aiInstruction","aiFillEnabled","createdAt","updatedAt"],"additionalProperties":false},"CreateCustomFieldBody":{"type":"object","properties":{"label":{"description":"Display label of the custom field. Not required to be unique.","type":"string","minLength":1,"maxLength":120},"fieldType":{"description":"Type of data this field holds.","type":"string","enum":["SELECT","MULTI_SELECT","CHECKBOX","TEXT","DATE","NUMBER","URL","IMAGE"]},"applyTo":{"description":"Entity types this field applies to. One or more of DEVICE, ACCESSORY, EMPLOYEE, ORDER.","minItems":1,"type":"array","items":{"type":"string","enum":["DEVICE","ACCESSORY","EMPLOYEE","ORDER"]}},"options":{"description":"Option catalog. Only allowed (and required) for SELECT and MULTI_SELECT field types.","type":"array","items":{"type":"object","properties":{"value":{"type":"string","minLength":1,"maxLength":120}},"required":["value"]}},"aiInstruction":{"description":"Instruction telling the AI how to fill this field and what it means. Max 2000 characters.","anyOf":[{"type":"string","maxLength":2000},{"type":"null"}]},"aiFillEnabled":{"description":"Enable AI auto-fill for this field. Cannot be true unless aiInstruction is non-empty.","type":"boolean"}},"required":["label","fieldType","applyTo"]},"UpdateCustomFieldBody":{"type":"object","properties":{"label":{"description":"New display label.","type":"string","minLength":1,"maxLength":120},"applyTo":{"description":"Entity types this field applies to (widen-only).","minItems":1,"type":"array","items":{"type":"string","enum":["DEVICE","ACCESSORY","EMPLOYEE","ORDER"]}},"optionsToAdd":{"description":"New option values to append. Only valid for SELECT / MULTI_SELECT fields.","minItems":1,"type":"array","items":{"type":"string","minLength":1,"maxLength":120}},"optionsToRename":{"description":"Existing options to rename, referenced by their stable option id.","minItems":1,"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"value":{"type":"string","minLength":1,"maxLength":120}},"required":["id","value"]}},"aiInstruction":{"description":"Instruction telling the AI how to fill this field. Max 2000 chars. Pass null to clear it.","anyOf":[{"type":"string","maxLength":2000},{"type":"null"}]},"aiFillEnabled":{"description":"Enable/disable AI auto-fill. Cannot be enabled while aiInstruction is empty; disabling keeps it.","type":"boolean"}}},"GetCompanies_Output":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"description":"Unique company identifier","type":"string"},"name":{"description":"Company display name","type":"string"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","name","createdAt","updatedAt"],"additionalProperties":false}},"pagination":{"type":"object","properties":{"totalElements":{"type":"integer","minimum":0,"maximum":9007199254740991},"totalPages":{"type":"integer","minimum":0,"maximum":9007199254740991},"page":{"type":"integer","minimum":1,"maximum":9007199254740991},"perPage":{"type":"integer","minimum":1,"maximum":100}},"required":["totalElements","totalPages","page","perPage"],"additionalProperties":false}},"required":["data","pagination"],"additionalProperties":false},"CreateCompanyBody":{"type":"object","properties":{"name":{"description":"Company display name. Must be unique across Primo","type":"string","minLength":1},"domainName":{"description":"Primary email domain of the company, e.g. acme.com","type":"string","minLength":1,"pattern":"^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\\.)+[a-z]{2,}$"}},"required":["name","domainName"]},"GetCompany_Output":{"type":"object","properties":{"id":{"type":"string","description":"Unique company identifier"},"name":{"type":"string","description":"Company display name"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"domainName":{"description":"Primary email domain of the company","anyOf":[{"type":"string"},{"type":"null"}]},"status":{"description":"Derived from the subscription: DEMO for a demo company, TRIAL / TRIAL_EXPIRED during a trial, DRAFT before activation, otherwise ACTIVE. A demo company reads DEMO from the moment the option is set, so use isDraft — not status — to tell whether it has been activated","anyOf":[{"type":"string","enum":["DRAFT","ACTIVE","INACTIVE","DEMO","TRIAL","TRIAL_EXPIRED"]},{"type":"null"}]},"isDraft":{"type":"boolean","description":"True until the company is activated: it is not usable yet, and its options can still be changed"},"options":{"anyOf":[{"type":"object","properties":{"mdmEnable":{"description":"Device management (MDM) is part of the company subscription","type":"boolean"},"saasEnable":{"description":"SaaS management (IAM) is part of the company subscription","type":"boolean"},"edrProducts":{"description":"EDR products subscribed by the company","type":"array","items":{"type":"string","enum":["SENTINEL_ONE_CONTROL","SENTINEL_ONE_COMPLETE","SENTINEL_ONE_VIGILANCE","THREATDOWN_STANDARD","THREATDOWN_MDR"]}},"isDemo":{"description":"The company is a demo environment and is never billed","type":"boolean"},"edrAdminContacts":{"description":"People the EDR console is opened in the name of, when an EDR product is subscribed","type":"array","items":{"type":"object","properties":{"firstName":{"type":"string","minLength":1},"lastName":{"type":"string","minLength":1},"email":{"type":"string","format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"}},"required":["firstName","lastName","email"],"additionalProperties":false}}},"required":["mdmEnable","saasEnable","edrProducts","isDemo","edrAdminContacts"],"additionalProperties":false},{"type":"null"}]}},"required":["id","name","createdAt","updatedAt","domainName","status","isDraft","options"],"additionalProperties":false},"UpdateCompanyOptionsBody":{"type":"object","properties":{"mdmEnable":{"type":"boolean"},"saasEnable":{"type":"boolean"},"edrProducts":{"type":"array","items":{"type":"string","enum":["SENTINEL_ONE_CONTROL","SENTINEL_ONE_COMPLETE","SENTINEL_ONE_VIGILANCE","THREATDOWN_STANDARD","THREATDOWN_MDR"]}},"isDemo":{"type":"boolean"},"edrAdminContacts":{"type":"array","items":{"type":"object","properties":{"firstName":{"type":"string","minLength":1},"lastName":{"type":"string","minLength":1},"email":{"type":"string","format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"}},"required":["firstName","lastName","email"]}}}},"GetDevices_Output":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"ownerId":{"description":"The ID of the employee assigned to this device","anyOf":[{"type":"string"},{"type":"null"}]},"name":{"anyOf":[{"type":"string"},{"type":"null"}]},"serialNumber":{"anyOf":[{"type":"string"},{"type":"null"}]},"computerName":{"description":"**Deprecated** — use `name` instead. This field will be removed on 2026-04-13.","deprecated":true,"anyOf":[{"type":"string"},{"type":"null"}]},"tags":{"type":"array","items":{"type":"string"}},"type":{"anyOf":[{"type":"string","enum":["LAPTOP","DESKTOP","TABLET","SMARTPHONE"]},{"type":"null"}]},"condition":{"description":"Physical condition recorded for the device","anyOf":[{"type":"string","enum":["BROKEN","FAIR","GOOD","EXCELLENT"]},{"type":"null"}]},"platform":{"anyOf":[{"type":"string","enum":["ANDROID","IOS","MACOS","WINDOWS","LINUX","CHROME_OS","IPADOS","UNKNOWN"]},{"type":"null"}]},"brand":{"anyOf":[{"type":"string"},{"type":"null"}]},"manufacturer":{"anyOf":[{"type":"string"},{"type":"null"}]},"modelName":{"anyOf":[{"type":"string"},{"type":"null"}]},"modelIdentifier":{"anyOf":[{"type":"string"},{"type":"null"}]},"year":{"anyOf":[{"type":"number"},{"type":"null"}]},"osVersion":{"anyOf":[{"type":"string"},{"type":"null"}]},"osName":{"anyOf":[{"type":"string"},{"type":"null"}]},"buildVersion":{"anyOf":[{"type":"string"},{"type":"null"}]},"osUpdateStatus":{"description":"OS update status of the device against the company's OS update policies: UP_TO_DATE, NOT_UP_TO_DATE, or NOT_SETUP when no OS update policy targets the device. Null when unknown.","anyOf":[{"type":"string","enum":["UP_TO_DATE","NOT_UP_TO_DATE","NOT_SETUP"]},{"type":"null"}]},"isEnrolled":{"type":"boolean"},"enrolledAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"disenrolledAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"purchaseDate":{"description":"Date the device was purchased","anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"decommissioningDate":{"description":"Date the device was decommissioned","anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"purchasePriceNoVAT":{"description":"Purchase price excluding VAT, in cents","anyOf":[{"anyOf":[{"type":"number"},{"type":"null"}]},{"type":"null"}]},"lockWipeStatus":{"description":"Current lock/wipe status of the device. LOCKING/LOCKED for lock operations, UNLOCKING for unlock in progress, WIPING/WIPED for wipe operations. Null when device is in normal state.","anyOf":[{"type":"string","enum":["LOCKED","LOCKING","UNLOCKING","WIPED","WIPING"]},{"type":"null"}]},"edrProvider":{"description":"EDR provider protecting the device: SENTINELONE, THREATDOWN, or null when no EDR (e.g. no EDR configured, or device not yet protected).","anyOf":[{"type":"string","enum":["SENTINELONE","THREATDOWN"]},{"type":"null"}]},"connectionStatus":{"description":"Device liveness: ONLINE (currently reachable), OFFLINE (not reachable but its agent is still live), INACTIVE (the agent stopped reporting — in practice no news for about a week), NOT_COMPATIBLE (iOS, iPadOS and Android have no liveness notion), or null when MDM is off for the device. INACTIVE follows from the agent being disabled, NOT from a threshold on `lastSeenAt` — to find devices silent for months, read `lastSeenAt`.","anyOf":[{"type":"string","enum":["ONLINE","OFFLINE","INACTIVE","NOT_COMPATIBLE"]},{"type":"null"}]},"lastSeenAt":{"description":"Last time the platform received anything from the device. The field to use for \"silent for N days\".","anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"lastScannedAt":{"description":"Last time the device's inventory was collected. A device can be heard from without being re-scanned.","anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"lastRestartAt":{"description":"Last time the device rebooted","anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"availableStatus":{"description":"Fleet-management status of the device: IN_USE, IN_STOCK or RETIRED","anyOf":[{"type":"string","enum":["IN_USE","IN_STOCK","RETIRED"]},{"type":"null"}]},"enrollmentType":{"description":"How the device was enrolled into MDM","anyOf":[{"type":"string","enum":["MANUAL","AUTOMATIC"]},{"type":"null"}]},"assetId":{"description":"Asset tag recorded by the company","anyOf":[{"type":"string"},{"type":"null"}]},"privateIpAddress":{"anyOf":[{"type":"string"},{"type":"null"}]},"publicIpAddress":{"anyOf":[{"type":"string"},{"type":"null"}]},"ram":{"description":"RAM in GB","anyOf":[{"type":"number"},{"type":"null"}]},"storage":{"description":"Disk size in GB","anyOf":[{"type":"number"},{"type":"null"}]},"processor":{"description":"Processor name, e.g. \"Apple M2 Pro\"","anyOf":[{"type":"string"},{"type":"null"}]},"cpuType":{"description":"Raw CPU type reported by the device, e.g. \"arm64e\" or \"x86_64\"","anyOf":[{"type":"string"},{"type":"null"}]},"cpuArchitecture":{"description":"CPU instruction-set architecture, derived from the device CPU. Use it to tell which architecture-specific software build a device can run. Null when the device has never been synced.","anyOf":[{"type":"string","enum":["ARM","X86"]},{"type":"null"}]},"inchScreenSize":{"description":"Screen size in inches","anyOf":[{"type":"number"},{"type":"null"}]},"keyboardLayout":{"anyOf":[{"type":"string","enum":["FRENCH","US_ENGLISH","ARABIC","CHINESE_PINYIN","CHINESE_ZHUYIN","DANISH","DUTCH","GERMAN","INTERNATIONAL_ENGLISH","ITALIAN","NORWEGIAN","PORTUGUESE","RUSSIAN","SPANISH","SPANISH_LATIN_AMERICA","SWEDISH","SWISS","TURKISH","UK_ENGLISH","UKRAINIAN","HEBREW","MACEDONIAN","JAPANESE_JIS"]},{"type":"null"}]},"batteryHealth":{"description":"Battery condition reported by the device: NORMAL, or SERVICE_RECOMMENDED when the battery should be serviced. Null when the device reported nothing.","anyOf":[{"type":"string","enum":["SERVICE_RECOMMENDED","NORMAL"]},{"type":"null"}]},"batteryCycleCount":{"anyOf":[{"type":"number"},{"type":"null"}]},"diskSpaceAvailableStatus":{"description":"Bucketed free-disk-space level derived from percentDiskSpaceAvailable","anyOf":[{"type":"string","enum":["LOW","MEDIUM","HIGH"]},{"type":"null"}]},"percentDiskSpaceAvailable":{"anyOf":[{"type":"number"},{"type":"null"}]},"encrypted":{"description":"Whether the device disk is encrypted. Null means the device reported nothing about encryption — not that it is unencrypted. To count the unencrypted fleet, read `false`; to size the blind spot, read `null`.","anyOf":[{"type":"boolean"},{"type":"null"}]},"encryptedAt":{"description":"First time the device was seen encrypted","anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"bootstrapTokenEscrowed":{"description":"Whether the macOS bootstrap token is escrowed. Null when the device reported nothing about it.","anyOf":[{"type":"boolean"},{"type":"null"}]},"bootstrapTokenEscrowedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","tags","isEnrolled","createdAt","updatedAt"],"additionalProperties":false}},"pagination":{"type":"object","properties":{"totalElements":{"type":"integer","minimum":0,"maximum":9007199254740991},"totalPages":{"type":"integer","minimum":0,"maximum":9007199254740991},"page":{"type":"integer","minimum":1,"maximum":9007199254740991},"perPage":{"type":"integer","minimum":1,"maximum":100}},"required":["totalElements","totalPages","page","perPage"],"additionalProperties":false}},"required":["data","pagination"],"additionalProperties":false},"GetDeviceFilterCatalog_Output":{"type":"object","properties":{"filterOptions":{"type":"array","items":{"type":"object","properties":{"key":{"description":"Where the clause is written in the filter: a criterion path (e.g. `mdmStatuses.online`) or a customFieldId.","type":"string"},"kind":{"type":"string","enum":["native","custom_field"]},"valueType":{"type":"string","enum":["multi_select","single_select","flag"]},"operationTypes":{"type":"array","items":{"type":"string","enum":["INCLUDE","EXCLUDE"]}},"supportsEmpty":{"description":"Whether the criterion can match the \"unset\" case.","type":"boolean"},"description":{"anyOf":[{"type":"string"},{"type":"null"}]},"values":{"description":"Allowed values. Absent for a `flag` criterion.","anyOf":[{"type":"array","items":{"type":"object","properties":{"value":{"type":"string"},"label":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["value"],"additionalProperties":false}},{"type":"null"}]},"fieldType":{"description":"Custom field type, for `custom_field` options only.","anyOf":[{"type":"string"},{"type":"null"}]}},"required":["key","kind","valueType","operationTypes","supportsEmpty"],"additionalProperties":false}},"supportsMatchAny":{"type":"boolean","description":"Whether the filter accepts a top-level `matchAny` toggle for OR semantics."}},"required":["filterOptions","supportsMatchAny"],"additionalProperties":false},"GetDevice_Output":{"type":"object","properties":{"id":{"type":"string"},"ownerId":{"description":"The ID of the employee assigned to this device","anyOf":[{"type":"string"},{"type":"null"}]},"name":{"anyOf":[{"type":"string"},{"type":"null"}]},"serialNumber":{"anyOf":[{"type":"string"},{"type":"null"}]},"computerName":{"description":"**Deprecated** — use `name` instead. This field will be removed on 2026-04-13.","deprecated":true,"anyOf":[{"type":"string"},{"type":"null"}]},"tags":{"type":"array","items":{"type":"string"}},"type":{"anyOf":[{"type":"string","enum":["LAPTOP","DESKTOP","TABLET","SMARTPHONE"]},{"type":"null"}]},"condition":{"description":"Physical condition recorded for the device","anyOf":[{"type":"string","enum":["BROKEN","FAIR","GOOD","EXCELLENT"]},{"type":"null"}]},"platform":{"anyOf":[{"type":"string","enum":["ANDROID","IOS","MACOS","WINDOWS","LINUX","CHROME_OS","IPADOS","UNKNOWN"]},{"type":"null"}]},"brand":{"anyOf":[{"type":"string"},{"type":"null"}]},"manufacturer":{"anyOf":[{"type":"string"},{"type":"null"}]},"modelName":{"anyOf":[{"type":"string"},{"type":"null"}]},"modelIdentifier":{"anyOf":[{"type":"string"},{"type":"null"}]},"year":{"anyOf":[{"type":"number"},{"type":"null"}]},"osVersion":{"anyOf":[{"type":"string"},{"type":"null"}]},"osName":{"anyOf":[{"type":"string"},{"type":"null"}]},"buildVersion":{"anyOf":[{"type":"string"},{"type":"null"}]},"osUpdateStatus":{"description":"OS update status of the device against the company's OS update policies: UP_TO_DATE, NOT_UP_TO_DATE, or NOT_SETUP when no OS update policy targets the device. Null when unknown.","anyOf":[{"type":"string","enum":["UP_TO_DATE","NOT_UP_TO_DATE","NOT_SETUP"]},{"type":"null"}]},"isEnrolled":{"type":"boolean"},"enrolledAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"disenrolledAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"purchaseDate":{"description":"Date the device was purchased","anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"decommissioningDate":{"description":"Date the device was decommissioned","anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"purchasePriceNoVAT":{"description":"Purchase price excluding VAT, in cents","anyOf":[{"anyOf":[{"type":"number"},{"type":"null"}]},{"type":"null"}]},"lockWipeStatus":{"description":"Current lock/wipe status of the device. LOCKING/LOCKED for lock operations, UNLOCKING for unlock in progress, WIPING/WIPED for wipe operations. Null when device is in normal state.","anyOf":[{"type":"string","enum":["LOCKED","LOCKING","UNLOCKING","WIPED","WIPING"]},{"type":"null"}]},"edrProvider":{"description":"EDR provider protecting the device: SENTINELONE, THREATDOWN, or null when no EDR (e.g. no EDR configured, or device not yet protected).","anyOf":[{"type":"string","enum":["SENTINELONE","THREATDOWN"]},{"type":"null"}]},"connectionStatus":{"description":"Device liveness: ONLINE (currently reachable), OFFLINE (not reachable but its agent is still live), INACTIVE (the agent stopped reporting — in practice no news for about a week), NOT_COMPATIBLE (iOS, iPadOS and Android have no liveness notion), or null when MDM is off for the device. INACTIVE follows from the agent being disabled, NOT from a threshold on `lastSeenAt` — to find devices silent for months, read `lastSeenAt`.","anyOf":[{"type":"string","enum":["ONLINE","OFFLINE","INACTIVE","NOT_COMPATIBLE"]},{"type":"null"}]},"lastSeenAt":{"description":"Last time the platform received anything from the device. The field to use for \"silent for N days\".","anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"lastScannedAt":{"description":"Last time the device's inventory was collected. A device can be heard from without being re-scanned.","anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"lastRestartAt":{"description":"Last time the device rebooted","anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"availableStatus":{"description":"Fleet-management status of the device: IN_USE, IN_STOCK or RETIRED","anyOf":[{"type":"string","enum":["IN_USE","IN_STOCK","RETIRED"]},{"type":"null"}]},"enrollmentType":{"description":"How the device was enrolled into MDM","anyOf":[{"type":"string","enum":["MANUAL","AUTOMATIC"]},{"type":"null"}]},"assetId":{"description":"Asset tag recorded by the company","anyOf":[{"type":"string"},{"type":"null"}]},"privateIpAddress":{"anyOf":[{"type":"string"},{"type":"null"}]},"publicIpAddress":{"anyOf":[{"type":"string"},{"type":"null"}]},"ram":{"description":"RAM in GB","anyOf":[{"type":"number"},{"type":"null"}]},"storage":{"description":"Disk size in GB","anyOf":[{"type":"number"},{"type":"null"}]},"processor":{"description":"Processor name, e.g. \"Apple M2 Pro\"","anyOf":[{"type":"string"},{"type":"null"}]},"cpuType":{"description":"Raw CPU type reported by the device, e.g. \"arm64e\" or \"x86_64\"","anyOf":[{"type":"string"},{"type":"null"}]},"cpuArchitecture":{"description":"CPU instruction-set architecture, derived from the device CPU. Use it to tell which architecture-specific software build a device can run. Null when the device has never been synced.","anyOf":[{"type":"string","enum":["ARM","X86"]},{"type":"null"}]},"inchScreenSize":{"description":"Screen size in inches","anyOf":[{"type":"number"},{"type":"null"}]},"keyboardLayout":{"anyOf":[{"type":"string","enum":["FRENCH","US_ENGLISH","ARABIC","CHINESE_PINYIN","CHINESE_ZHUYIN","DANISH","DUTCH","GERMAN","INTERNATIONAL_ENGLISH","ITALIAN","NORWEGIAN","PORTUGUESE","RUSSIAN","SPANISH","SPANISH_LATIN_AMERICA","SWEDISH","SWISS","TURKISH","UK_ENGLISH","UKRAINIAN","HEBREW","MACEDONIAN","JAPANESE_JIS"]},{"type":"null"}]},"batteryHealth":{"description":"Battery condition reported by the device: NORMAL, or SERVICE_RECOMMENDED when the battery should be serviced. Null when the device reported nothing.","anyOf":[{"type":"string","enum":["SERVICE_RECOMMENDED","NORMAL"]},{"type":"null"}]},"batteryCycleCount":{"anyOf":[{"type":"number"},{"type":"null"}]},"diskSpaceAvailableStatus":{"description":"Bucketed free-disk-space level derived from percentDiskSpaceAvailable","anyOf":[{"type":"string","enum":["LOW","MEDIUM","HIGH"]},{"type":"null"}]},"percentDiskSpaceAvailable":{"anyOf":[{"type":"number"},{"type":"null"}]},"encrypted":{"description":"Whether the device disk is encrypted. Null means the device reported nothing about encryption — not that it is unencrypted. To count the unencrypted fleet, read `false`; to size the blind spot, read `null`.","anyOf":[{"type":"boolean"},{"type":"null"}]},"encryptedAt":{"description":"First time the device was seen encrypted","anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"bootstrapTokenEscrowed":{"description":"Whether the macOS bootstrap token is escrowed. Null when the device reported nothing about it.","anyOf":[{"type":"boolean"},{"type":"null"}]},"bootstrapTokenEscrowedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"imeis":{"type":"array","description":"IMEIs of the device, digits only, one per SIM slot (a dual-SIM iPhone has two). Reported by the MDM for company-owned iPhones, cellular iPads and Android phones; empty when it reported none.","items":{"type":"string"}}},"required":["id","tags","isEnrolled","createdAt","updatedAt","imeis"],"additionalProperties":false},"CreateDeviceBody":{"type":"object","properties":{"purchaseDate":{"description":"Date the device was purchased, as an ISO 8601 date (YYYY-MM-DD) or datetime","anyOf":[{"anyOf":[{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}]},{"type":"null"}]},"decommissioningDate":{"description":"Date the device was decommissioned, as an ISO 8601 date (YYYY-MM-DD) or datetime","anyOf":[{"anyOf":[{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}]},{"type":"null"}]},"purchasePriceNoVAT":{"description":"Purchase price excluding VAT, in cents","anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"serialNumber":{"description":"Serial number of the device","anyOf":[{"type":"string"},{"type":"null"}]},"name":{"description":"Display name of the device","anyOf":[{"type":"string"},{"type":"null"}]},"platform":{"description":"Operating system platform (e.g. MACOS, WINDOWS, LINUX, IOS, ANDROID, CHROMEOS)","anyOf":[{"type":"string","enum":["ANDROID","IOS","MACOS","WINDOWS","LINUX","CHROME_OS","IPADOS","UNKNOWN"]},{"type":"null"}]},"type":{"description":"Device type (LAPTOP, DESKTOP, TABLET, SMARTPHONE)","anyOf":[{"type":"string","enum":["LAPTOP","DESKTOP","TABLET","SMARTPHONE"]},{"type":"null"}]},"brand":{"description":"Brand or manufacturer name","anyOf":[{"type":"string"},{"type":"null"}]},"modelName":{"description":"Model name of the device","anyOf":[{"type":"string"},{"type":"null"}]},"year":{"description":"Year the device was manufactured","anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"ownerId":{"description":"ID of the employee to assign this device to","anyOf":[{"type":"string"},{"type":"null"}]},"tags":{"description":"List of tags","type":"array","items":{"type":"string"}}}},"UpdateDeviceBody":{"type":"object","properties":{"purchaseDate":{"description":"Date the device was purchased, as an ISO 8601 date (YYYY-MM-DD) or datetime","anyOf":[{"anyOf":[{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}]},{"type":"null"}]},"decommissioningDate":{"description":"Date the device was decommissioned, as an ISO 8601 date (YYYY-MM-DD) or datetime","anyOf":[{"anyOf":[{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}]},{"type":"null"}]},"purchasePriceNoVAT":{"description":"Purchase price excluding VAT, in cents","anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"ownerId":{"description":"ID of the employee this device is assigned to. Null unassigns it. Must be an employee of your company.","anyOf":[{"type":"string","pattern":"^[a-f\\d]{24}$"},{"type":"null"}]},"name":{"description":"Display name of the device. Cannot be emptied. Rejected when a device naming MDM control drives the name. On Windows and Linux, letters, digits and hyphens only, starting and ending with a letter or a digit.","type":"string","minLength":1},"assetId":{"description":"Asset tag recorded by the company. Free text, null clears it.","anyOf":[{"type":"string"},{"type":"null"}]},"condition":{"description":"Physical condition of the device. One of BROKEN, FAIR, GOOD, EXCELLENT.","anyOf":[{"type":"string","enum":["BROKEN","FAIR","GOOD","EXCELLENT"]},{"type":"null"}]},"keyboardLayout":{"description":"Keyboard layout of the device, e.g. FRENCH, US_ENGLISH — see the enum for the full list.","anyOf":[{"type":"string","enum":["FRENCH","US_ENGLISH","ARABIC","CHINESE_PINYIN","CHINESE_ZHUYIN","DANISH","DUTCH","GERMAN","INTERNATIONAL_ENGLISH","ITALIAN","NORWEGIAN","PORTUGUESE","RUSSIAN","SPANISH","SPANISH_LATIN_AMERICA","SWEDISH","SWISS","TURKISH","UK_ENGLISH","UKRAINIAN","HEBREW","MACEDONIAN","JAPANESE_JIS"]},{"type":"null"}]},"inchScreenSize":{"description":"Screen size in inches, e.g. 14 or 13.6.","anyOf":[{"type":"number"},{"type":"null"}]},"brand":{"description":"Brand or manufacturer name, e.g. \"APPLE\", \"LENOVO\".","anyOf":[{"type":"string"},{"type":"null"}]},"modelName":{"description":"Commercial model name, e.g. \"MacBook Pro 14\"\".","anyOf":[{"type":"string"},{"type":"null"}]},"year":{"description":"Year the device was manufactured, e.g. 2024.","anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"serialNumber":{"description":"Serial number of the device. Must be unique in your company. Only editable while the device is not enrolled in MDM — MDM owns this value on an enrolled device.","anyOf":[{"type":"string"},{"type":"null"}]},"modelIdentifier":{"description":"Model identifier reported by the device, e.g. \"MacBookPro18,3\". Only editable while the device is not enrolled in MDM — MDM owns this value on an enrolled device.","anyOf":[{"type":"string"},{"type":"null"}]},"type":{"description":"Device type: LAPTOP, DESKTOP, TABLET, SMARTPHONE. Only editable while the device is not enrolled in MDM — MDM owns this value on an enrolled device. DESKTOP is the exception: the MDM cannot detect a desktop, so it can be set on an enrolled device, and changed back from it.","anyOf":[{"type":"string","enum":["LAPTOP","DESKTOP","TABLET","SMARTPHONE"]},{"type":"null"}]},"processor":{"description":"Processor name, e.g. \"Apple M2 Pro\". Only editable while the device is not enrolled in MDM — MDM owns this value on an enrolled device.","anyOf":[{"type":"string"},{"type":"null"}]},"ram":{"description":"RAM in GB, e.g. 16. Only editable while the device is not enrolled in MDM — MDM owns this value on an enrolled device.","anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"storage":{"description":"Disk size in GB, e.g. 512. Only editable while the device is not enrolled in MDM — MDM owns this value on an enrolled device.","anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"batteryHealth":{"description":"Battery condition: SERVICE_RECOMMENDED or NORMAL. Only editable while the device is not enrolled in MDM — MDM owns this value on an enrolled device.","anyOf":[{"type":"string","enum":["SERVICE_RECOMMENDED","NORMAL"]},{"type":"null"}]}}},"UpdateDevicesBody":{"type":"object","properties":{"items":{"description":"Device updates to apply. Each item targets one `deviceId`, which must be unique within the batch, and carries the same fields as `updateDevice`. Up to 100 items per call. Writes are best-effort: inspect the per-item `results` to learn which succeeded — the HTTP status is 200 even when some items fail.","minItems":1,"maxItems":100,"type":"array","items":{"type":"object","properties":{"purchaseDate":{"description":"Date the device was purchased, as an ISO 8601 date (YYYY-MM-DD) or datetime","anyOf":[{"anyOf":[{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}]},{"type":"null"}]},"decommissioningDate":{"description":"Date the device was decommissioned, as an ISO 8601 date (YYYY-MM-DD) or datetime","anyOf":[{"anyOf":[{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}]},{"type":"null"}]},"purchasePriceNoVAT":{"description":"Purchase price excluding VAT, in cents","anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"ownerId":{"description":"ID of the employee this device is assigned to. Null unassigns it. Must be an employee of your company.","anyOf":[{"type":"string","pattern":"^[a-f\\d]{24}$"},{"type":"null"}]},"name":{"description":"Display name of the device. Cannot be emptied. Rejected when a device naming MDM control drives the name. On Windows and Linux, letters, digits and hyphens only, starting and ending with a letter or a digit.","type":"string","minLength":1},"assetId":{"description":"Asset tag recorded by the company. Free text, null clears it.","anyOf":[{"type":"string"},{"type":"null"}]},"condition":{"description":"Physical condition of the device. One of BROKEN, FAIR, GOOD, EXCELLENT.","anyOf":[{"type":"string","enum":["BROKEN","FAIR","GOOD","EXCELLENT"]},{"type":"null"}]},"keyboardLayout":{"description":"Keyboard layout of the device, e.g. FRENCH, US_ENGLISH — see the enum for the full list.","anyOf":[{"type":"string","enum":["FRENCH","US_ENGLISH","ARABIC","CHINESE_PINYIN","CHINESE_ZHUYIN","DANISH","DUTCH","GERMAN","INTERNATIONAL_ENGLISH","ITALIAN","NORWEGIAN","PORTUGUESE","RUSSIAN","SPANISH","SPANISH_LATIN_AMERICA","SWEDISH","SWISS","TURKISH","UK_ENGLISH","UKRAINIAN","HEBREW","MACEDONIAN","JAPANESE_JIS"]},{"type":"null"}]},"inchScreenSize":{"description":"Screen size in inches, e.g. 14 or 13.6.","anyOf":[{"type":"number"},{"type":"null"}]},"brand":{"description":"Brand or manufacturer name, e.g. \"APPLE\", \"LENOVO\".","anyOf":[{"type":"string"},{"type":"null"}]},"modelName":{"description":"Commercial model name, e.g. \"MacBook Pro 14\"\".","anyOf":[{"type":"string"},{"type":"null"}]},"year":{"description":"Year the device was manufactured, e.g. 2024.","anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"serialNumber":{"description":"Serial number of the device. Must be unique in your company. Only editable while the device is not enrolled in MDM — MDM owns this value on an enrolled device.","anyOf":[{"type":"string"},{"type":"null"}]},"modelIdentifier":{"description":"Model identifier reported by the device, e.g. \"MacBookPro18,3\". Only editable while the device is not enrolled in MDM — MDM owns this value on an enrolled device.","anyOf":[{"type":"string"},{"type":"null"}]},"type":{"description":"Device type: LAPTOP, DESKTOP, TABLET, SMARTPHONE. Only editable while the device is not enrolled in MDM — MDM owns this value on an enrolled device. DESKTOP is the exception: the MDM cannot detect a desktop, so it can be set on an enrolled device, and changed back from it.","anyOf":[{"type":"string","enum":["LAPTOP","DESKTOP","TABLET","SMARTPHONE"]},{"type":"null"}]},"processor":{"description":"Processor name, e.g. \"Apple M2 Pro\". Only editable while the device is not enrolled in MDM — MDM owns this value on an enrolled device.","anyOf":[{"type":"string"},{"type":"null"}]},"ram":{"description":"RAM in GB, e.g. 16. Only editable while the device is not enrolled in MDM — MDM owns this value on an enrolled device.","anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"storage":{"description":"Disk size in GB, e.g. 512. Only editable while the device is not enrolled in MDM — MDM owns this value on an enrolled device.","anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"batteryHealth":{"description":"Battery condition: SERVICE_RECOMMENDED or NORMAL. Only editable while the device is not enrolled in MDM — MDM owns this value on an enrolled device.","anyOf":[{"type":"string","enum":["SERVICE_RECOMMENDED","NORMAL"]},{"type":"null"}]},"deviceId":{"description":"Device id to update.","type":"string"}},"required":["deviceId"]}}},"required":["items"]},"UpdateDevicesResult_Output":{"type":"object","properties":{"successCount":{"type":"integer","description":"Number of devices updated successfully.","minimum":-9007199254740991,"maximum":9007199254740991},"failureCount":{"type":"integer","description":"Number of devices that failed to update.","minimum":-9007199254740991,"maximum":9007199254740991},"results":{"type":"array","description":"Per-item outcome, in the same order as the input `items`.","items":{"type":"object","properties":{"deviceId":{"type":"string"},"status":{"type":"string","enum":["ok","error"]},"errorCode":{"description":"Machine-readable error code when status is \"error\".","anyOf":[{"type":"string"},{"type":"null"}]},"message":{"description":"Human-readable error detail when status is \"error\".","anyOf":[{"type":"string"},{"type":"null"}]}},"required":["deviceId","status"],"additionalProperties":false}}},"required":["successCount","failureCount","results"],"additionalProperties":false},"LockDevice_Output":{"type":"object","properties":{"success":{"type":"boolean","const":true},"platform":{"type":"string","description":"The platform of the locked device","enum":["ANDROID","IOS","MACOS","WINDOWS","LINUX","CHROME_OS","IPADOS","UNKNOWN"]},"message":{"type":"string","description":"A human-readable description of the lock operation"}},"required":["success","platform","message"],"additionalProperties":false},"UnlockDevice_Output":{"type":"object","properties":{"success":{"type":"boolean","const":true},"platform":{"type":"string","description":"The platform of the unlocked device","enum":["ANDROID","IOS","MACOS","WINDOWS","LINUX","CHROME_OS","IPADOS","UNKNOWN"]},"unlockPin":{"description":"Unlock PIN to enter on the device (macOS only). Null for platforms where unlock is handled remotely.","anyOf":[{"type":"string"},{"type":"null"}]},"message":{"type":"string","description":"A human-readable description of the unlock operation"}},"required":["success","platform","message"],"additionalProperties":false},"WipeDeviceBody":{"type":"object","properties":{"wipeType":{"description":"Type of wipe to perform. Only applicable for Windows devices. SOFT resets the device but preserves user data, HARD performs a complete factory reset. Ignored for other platforms.","type":"string","enum":["SOFT","HARD"]}}},"WipeDevice_Output":{"type":"object","properties":{"success":{"type":"boolean","const":true},"platform":{"type":"string","description":"The platform of the wiped device","enum":["ANDROID","IOS","MACOS","WINDOWS","LINUX","CHROME_OS","IPADOS","UNKNOWN"]},"wipeType":{"description":"The type of wipe that was performed. Only present for Windows devices (SOFT or HARD). Null for other platforms.","anyOf":[{"type":"string","enum":["SOFT","HARD"]},{"type":"null"}]},"message":{"type":"string","description":"A human-readable description of the wipe operation"}},"required":["success","platform","message"],"additionalProperties":false},"RunDeviceScriptBody":{"type":"object","properties":{"script":{"description":"What to run: `{ \"scriptId\": 12 }` for a script from the catalog, or `{ \"contents\": \"...\" }` to send the source inline. An inline run may only target a single device.","anyOf":[{"type":"object","properties":{"scriptId":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991}},"required":["scriptId"]},{"type":"object","properties":{"contents":{"type":"string","minLength":1,"maxLength":10000}},"required":["contents"]}]}},"required":["script"]},"RunScript_Output":{"type":"object","properties":{"id":{"type":"string"},"script":{"type":"object","properties":{"scriptId":{"description":"Saved script that was run, or null when the contents were sent inline.","anyOf":[{"type":"number"},{"type":"null"}]},"name":{"description":"Script name at the time of the run. Null for an inline run.","anyOf":[{"type":"string"},{"type":"null"}]}},"required":["scriptId","name"],"additionalProperties":false},"target":{"description":"The target as submitted.","anyOf":[{"type":"object","properties":{"type":{"type":"string","const":"all"}},"required":["type"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"deviceGroups"},"deviceGroupIds":{"minItems":1,"type":"array","items":{"type":"string"}}},"required":["type","deviceGroupIds"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"devices"},"deviceIds":{"minItems":1,"type":"array","items":{"type":"string"}}},"required":["type","deviceIds"],"additionalProperties":false}]},"platforms":{"type":"array","items":{"type":"string","enum":["macos","windows","linux"]}},"contents":{"type":"string","description":"Full source of the script as executed."},"totalExecutions":{"type":"number","description":"Number of devices the run resolved to."},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"executions":{"type":"array","description":"One execution per resolved device, all `pending` at creation. Poll `getScriptRun` or `getScriptRunExecutions` for outcomes.","items":{"type":"object","properties":{"id":{"type":"string"},"runId":{"description":"Identifier of the script run this execution belongs to.","type":"string"},"deviceId":{"type":"string"},"status":{"description":"Outcome on one device. `pending`: queued, the device may be offline. `success`: ran with exit code 0. `failed`: ran and exited with a non-zero code. `not_run`: the device never started the script — read `message` for the reason (missing interpreter, incompatible host, host outside the Fleet team). `timeout`: exceeded the execution limit, or the device reported nothing within 24 hours. `cancelled`: cancelled before running.","type":"string","enum":["pending","success","failed","not_run","timeout","cancelled"]},"output":{"description":"Combined stdout/stderr once the execution completes. Null while pending.","anyOf":[{"type":"string"},{"type":"null"}]},"message":{"description":"Diagnostic reported by the MDM when the script did not run or did not complete. Null otherwise.","anyOf":[{"type":"string"},{"type":"null"}]},"exitCode":{"description":"Process exit code once the execution completes. Null while pending.","anyOf":[{"type":"number"},{"type":"null"}]},"runtime":{"description":"Duration in seconds once the execution completes. Null while pending.","anyOf":[{"type":"number"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","runId","deviceId","status","output","message","exitCode","runtime","createdAt","updatedAt"],"additionalProperties":false}}},"required":["id","script","target","platforms","contents","totalExecutions","createdAt","executions"],"additionalProperties":false},"GetDeviceScriptExecutions_Output":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"runId":{"description":"Identifier of the script run this execution belongs to.","type":"string"},"deviceId":{"type":"string"},"status":{"description":"Outcome on one device. `pending`: queued, the device may be offline. `success`: ran with exit code 0. `failed`: ran and exited with a non-zero code. `not_run`: the device never started the script — read `message` for the reason (missing interpreter, incompatible host, host outside the Fleet team). `timeout`: exceeded the execution limit, or the device reported nothing within 24 hours. `cancelled`: cancelled before running.","type":"string","enum":["pending","success","failed","not_run","timeout","cancelled"]},"output":{"description":"Combined stdout/stderr once the execution completes. Null while pending.","anyOf":[{"type":"string"},{"type":"null"}]},"message":{"description":"Diagnostic reported by the MDM when the script did not run or did not complete. Null otherwise.","anyOf":[{"type":"string"},{"type":"null"}]},"exitCode":{"description":"Process exit code once the execution completes. Null while pending.","anyOf":[{"type":"number"},{"type":"null"}]},"runtime":{"description":"Duration in seconds once the execution completes. Null while pending.","anyOf":[{"type":"number"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"script":{"description":"The script as executed. `scriptId` and `name` are null when the run used inline contents.","anyOf":[{"type":"object","properties":{"scriptId":{"anyOf":[{"type":"number"},{"type":"null"}]},"name":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["scriptId","name"],"additionalProperties":false},{"type":"null"}]}},"required":["id","runId","deviceId","status","output","message","exitCode","runtime","createdAt","updatedAt","script"],"additionalProperties":false}},"pagination":{"type":"object","properties":{"totalElements":{"type":"integer","minimum":0,"maximum":9007199254740991},"totalPages":{"type":"integer","minimum":0,"maximum":9007199254740991},"page":{"type":"integer","minimum":1,"maximum":9007199254740991},"perPage":{"type":"integer","minimum":1,"maximum":100}},"required":["totalElements","totalPages","page","perPage"],"additionalProperties":false}},"required":["data","pagination"],"additionalProperties":false},"DeleteDevice_Output":{"type":"object","properties":{"success":{"type":"boolean","const":true}},"required":["success"],"additionalProperties":false},"RetireDeviceBody":{"type":"object","properties":{"deviceName":{"description":"New name to assign to the device after retirement","type":"string"},"dataAction":{"description":"WIPE, SOFT_WIPE or HARD_WIPE sends an MDM wipe during retirement; LOCK, NOTHING or no value sends an MDM disenroll instead. A wipe needs the MDM host record that a completed disenrollment removes, and fails with 502 without it.","anyOf":[{"type":"string","enum":["WIPE","SOFT_WIPE","HARD_WIPE","LOCK","NOTHING"]},{"type":"null"}]},"condition":{"description":"Physical condition of the device","anyOf":[{"type":"string","enum":["BROKEN","FAIR","GOOD","EXCELLENT"]},{"type":"null"}]},"notes":{"description":"Optional notes about the retirement","anyOf":[{"type":"string"},{"type":"null"}]}},"required":["deviceName"]},"RetireDevice_Output":{"type":"object","properties":{"success":{"type":"boolean","const":true}},"required":["success"],"additionalProperties":false},"RebootDevice_Output":{"type":"object","properties":{"success":{"type":"boolean","const":true}},"required":["success"],"additionalProperties":false},"DisenrollDevice_Output":{"type":"object","properties":{"success":{"type":"boolean","const":true}},"required":["success"],"additionalProperties":false},"MoveToStock_Output":{"type":"object","properties":{"success":{"type":"boolean","const":true}},"required":["success"],"additionalProperties":false},"MoveToInUse_Output":{"type":"object","properties":{"success":{"type":"boolean","const":true}},"required":["success"],"additionalProperties":false},"PutBackInStock_Output":{"type":"object","properties":{"success":{"type":"boolean","const":true}},"required":["success"],"additionalProperties":false},"UpdateDeviceOwnerBody":{"type":"object","properties":{"ownerId":{"description":"ID of the employee to assign this device to, or null to unassign","anyOf":[{"type":"string"},{"type":"null"}]}},"required":["ownerId"]},"UpdateDeviceOwnerResponse_Output":{"type":"object","properties":{"success":{"type":"boolean","const":true}},"required":["success"],"additionalProperties":false},"UpdateDeviceTagsBody":{"type":"object","properties":{"tags":{"description":"New list of tags for the device (replaces existing tags)","type":"array","items":{"type":"string"}}},"required":["tags"]},"UpdateDeviceTagsResponse_Output":{"type":"object","properties":{"success":{"type":"boolean","const":true}},"required":["success"],"additionalProperties":false},"GetDeviceEvents_Output":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"description":"Event type name (e.g. LOCK_TRIGGERED, REBOOT_TRIGGERED, DISENROLL_TRIGGERED)","type":"string"},"deviceId":{"type":"string"},"companyId":{"type":"string"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"initiatorId":{"description":"ID of the employee who triggered the event, if applicable","anyOf":[{"type":"string"},{"type":"null"}]},"initiatorName":{"description":"Name or email of the initiator (used when initiator is not an employee)","anyOf":[{"type":"string"},{"type":"null"}]},"status":{"description":"Current status of the event (for async operations)","anyOf":[{"type":"string"},{"type":"null"}]},"isAsync":{"description":"Whether the event tracks an async operation","type":"boolean"},"properties":{"description":"Event-specific properties","anyOf":[{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},{"type":"null"}]},"scheduledDate":{"description":"Scheduled execution date for deferred events","anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]}},"required":["id","name","deviceId","companyId","createdAt","updatedAt","isAsync"],"additionalProperties":false}}},"required":["data"],"additionalProperties":false},"GetDeviceUsers_Output":{"type":"object","properties":{"users":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"username":{"type":"string"},"uid":{"description":"Platform-level user identifier (e.g. macOS UID), when known.","anyOf":[{"type":"string"},{"type":"null"}]},"rights":{"description":"Local privilege level of the account on the device. ADMIN = local administrator, USER = standard user, UNKNOWN = not yet reported by the MDM.","type":"string","enum":["ADMIN","USER","UNKNOWN"]},"accountType":{"description":"Always LOCAL — only on-device local accounts are returned.","type":"string","enum":["LOCAL","REMOTE"]},"groupName":{"anyOf":[{"type":"string"},{"type":"null"}]},"secureTokenGranted":{"description":"macOS: whether the account holds a SecureToken.","anyOf":[{"type":"boolean"},{"type":"null"}]},"password":{"description":"Current account password in plaintext, when Primo manages it; null when unknown/unmanaged.","anyOf":[{"type":"string"},{"type":"null"}]}},"required":["id","username","uid","rights","accountType","groupName","secureTokenGranted","password"],"additionalProperties":false}}},"required":["users"],"additionalProperties":false},"GetDevicesUsersBody":{"type":"object","properties":{"deviceIds":{"description":"Device ids to fetch local user accounts for. Up to 200 per call.","minItems":1,"maxItems":200,"type":"array","items":{"type":"string"}}},"required":["deviceIds"]},"GetDevicesUsers_Output":{"type":"object","properties":{"items":{"type":"array","description":"Local user accounts grouped by device id.","items":{"type":"object","properties":{"deviceId":{"type":"string"},"users":{"description":"Local user accounts on this device. Empty when the device has no local account, does not exist, or does not belong to your company.","type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"username":{"type":"string"},"uid":{"description":"Platform-level user identifier (e.g. macOS UID), when known.","anyOf":[{"type":"string"},{"type":"null"}]},"rights":{"description":"Local privilege level of the account on the device. ADMIN = local administrator, USER = standard user, UNKNOWN = not yet reported by the MDM.","type":"string","enum":["ADMIN","USER","UNKNOWN"]},"accountType":{"description":"Always LOCAL — only on-device local accounts are returned.","type":"string","enum":["LOCAL","REMOTE"]},"groupName":{"anyOf":[{"type":"string"},{"type":"null"}]},"secureTokenGranted":{"description":"macOS: whether the account holds a SecureToken.","anyOf":[{"type":"boolean"},{"type":"null"}]},"password":{"description":"Current account password in plaintext, when Primo manages it; null when unknown/unmanaged.","anyOf":[{"type":"string"},{"type":"null"}]}},"required":["id","username","uid","rights","accountType","groupName","secureTokenGranted","password"],"additionalProperties":false}}},"required":["deviceId","users"],"additionalProperties":false}}},"required":["items"],"additionalProperties":false},"GetDeviceCodeHistory_Output":{"type":"object","properties":{"data":{"type":"array","description":"Code history entries, newest first.","items":{"type":"object","properties":{"type":{"description":"Type of code: ICLOUD_BYPASS_CODE, UNLOCK_PIN, RECOVERY_KEY, or RECOVERY_OS.","type":"string","enum":["ICLOUD_BYPASS_CODE","UNLOCK_PIN","RECOVERY_KEY","RECOVERY_OS"]},"code":{"description":"Decrypted code value.","type":"string"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["type","code","createdAt"],"additionalProperties":false}}},"required":["data"],"additionalProperties":false},"GetDeviceReachability_Output":{"type":"object","properties":{"reachabilityPercent":{"description":"Share of the syncs of the last 7 days that saw the device online, 0 to 100. Null without a sample.","anyOf":[{"type":"number"},{"type":"null"}]},"samples":{"type":"array","description":"One sample per 30-minute Fleet sync of the last 7 days, oldest first. No sync runs from 02:00 to 05:59 UTC.","items":{"type":"object","properties":{"slotStartedAt":{"description":"Start of the 30-minute slot the Fleet sync ran in.","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"isOnline":{"description":"Whether Fleet saw the device online at that sync.","type":"boolean"}},"required":["slotStartedAt","isOnline"],"additionalProperties":false}}},"required":["reachabilityPercent","samples"],"additionalProperties":false},"GetDevicesCodeHistoryBody":{"type":"object","properties":{"deviceIds":{"description":"Device ids to fetch code history for. Up to 200 per call.","minItems":1,"maxItems":200,"type":"array","items":{"type":"string"}},"type":{"description":"Optional filter: ICLOUD_BYPASS_CODE, UNLOCK_PIN, RECOVERY_KEY, or RECOVERY_OS.","type":"string","enum":["ICLOUD_BYPASS_CODE","UNLOCK_PIN","RECOVERY_KEY","RECOVERY_OS"]}},"required":["deviceIds"]},"GetDevicesCodeHistory_Output":{"type":"object","properties":{"items":{"type":"array","description":"Code history grouped by device id.","items":{"type":"object","properties":{"deviceId":{"type":"string"},"data":{"description":"Code history entries for this device, newest first. Empty when the device has no history, does not exist, or does not belong to your company.","type":"array","items":{"type":"object","properties":{"type":{"description":"Type of code: ICLOUD_BYPASS_CODE, UNLOCK_PIN, RECOVERY_KEY, or RECOVERY_OS.","type":"string","enum":["ICLOUD_BYPASS_CODE","UNLOCK_PIN","RECOVERY_KEY","RECOVERY_OS"]},"code":{"description":"Decrypted code value.","type":"string"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["type","code","createdAt"],"additionalProperties":false}}},"required":["deviceId","data"],"additionalProperties":false}}},"required":["items"],"additionalProperties":false},"GetDeviceCustomFields_Output":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"field":{"type":"object","properties":{"id":{"description":"CustomField id (MongoDB ObjectId string).","type":"string"},"label":{"type":"string"},"fieldType":{"description":"Type of data this field holds.","type":"string","enum":["SELECT","MULTI_SELECT","CHECKBOX","TEXT","DATE","NUMBER","URL","IMAGE"]},"applyTo":{"type":"array","items":{"type":"string","enum":["DEVICE","ACCESSORY","EMPLOYEE","ORDER"]}},"options":{"description":"Option catalog. Non-empty only for SELECT / MULTI_SELECT fields. Use option `id` when writing values.","type":"array","items":{"type":"object","properties":{"id":{"description":"Stable UUID of the option. Use this id for SELECT / MULTI_SELECT value writes.","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"value":{"description":"Display label of the option (mutable — ids are the stable identity).","type":"string"}},"required":["id","value"],"additionalProperties":false}}},"required":["id","label","fieldType","applyTo","options"],"additionalProperties":false},"value":{"description":"Current stored value for this field on this device, or null when unset. For SELECT / MULTI_SELECT the value is the option id (or array of ids). For CHECKBOX it is a boolean. For DATE it is an ISO date string.","anyOf":[{"type":"boolean"},{"type":"number"},{"type":"string"},{"type":"array","items":{"type":"string"}},{"type":"null"}]}},"required":["field","value"],"additionalProperties":false}}},"required":["items"],"additionalProperties":false},"GetDevicesCustomFieldsBody":{"type":"object","properties":{"deviceIds":{"description":"Device ids to fetch custom fields for. Up to 500 per call.","minItems":1,"maxItems":500,"type":"array","items":{"type":"string"}}},"required":["deviceIds"]},"GetDevicesCustomFields_Output":{"type":"object","properties":{"items":{"type":"array","description":"Custom fields grouped by device id, in the same order as the input `deviceIds`.","items":{"type":"object","properties":{"deviceId":{"type":"string"},"customFields":{"type":"array","items":{"type":"object","properties":{"field":{"type":"object","properties":{"id":{"description":"CustomField id (MongoDB ObjectId string).","type":"string"},"label":{"type":"string"},"fieldType":{"description":"Type of data this field holds.","type":"string","enum":["SELECT","MULTI_SELECT","CHECKBOX","TEXT","DATE","NUMBER","URL","IMAGE"]},"applyTo":{"type":"array","items":{"type":"string","enum":["DEVICE","ACCESSORY","EMPLOYEE","ORDER"]}},"options":{"description":"Option catalog. Non-empty only for SELECT / MULTI_SELECT fields. Use option `id` when writing values.","type":"array","items":{"type":"object","properties":{"id":{"description":"Stable UUID of the option. Use this id for SELECT / MULTI_SELECT value writes.","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"value":{"description":"Display label of the option (mutable — ids are the stable identity).","type":"string"}},"required":["id","value"],"additionalProperties":false}}},"required":["id","label","fieldType","applyTo","options"],"additionalProperties":false},"value":{"description":"Current stored value for this field on this device, or null when unset. For SELECT / MULTI_SELECT the value is the option id (or array of ids). For CHECKBOX it is a boolean. For DATE it is an ISO date string.","anyOf":[{"type":"boolean"},{"type":"number"},{"type":"string"},{"type":"array","items":{"type":"string"}},{"type":"null"}]}},"required":["field","value"],"additionalProperties":false}}},"required":["deviceId","customFields"],"additionalProperties":false}}},"required":["items"],"additionalProperties":false},"SetDeviceCustomFieldValueBody":{"type":"object","properties":{"value":{"description":"Value to set. Must conform to the field type. Pass null to clear an existing value. For SELECT supply the option id (string). For MULTI_SELECT supply an array of option ids.","anyOf":[{"type":"boolean"},{"type":"number"},{"type":"string"},{"type":"array","items":{"type":"string"}},{"type":"null"}]}},"required":["value"]},"DeviceCustomFieldItem_Output":{"type":"object","properties":{"field":{"type":"object","properties":{"id":{"description":"CustomField id (MongoDB ObjectId string).","type":"string"},"label":{"type":"string"},"fieldType":{"description":"Type of data this field holds.","type":"string","enum":["SELECT","MULTI_SELECT","CHECKBOX","TEXT","DATE","NUMBER","URL","IMAGE"]},"applyTo":{"type":"array","items":{"type":"string","enum":["DEVICE","ACCESSORY","EMPLOYEE","ORDER"]}},"options":{"description":"Option catalog. Non-empty only for SELECT / MULTI_SELECT fields. Use option `id` when writing values.","type":"array","items":{"type":"object","properties":{"id":{"description":"Stable UUID of the option. Use this id for SELECT / MULTI_SELECT value writes.","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"value":{"description":"Display label of the option (mutable — ids are the stable identity).","type":"string"}},"required":["id","value"],"additionalProperties":false}}},"required":["id","label","fieldType","applyTo","options"],"additionalProperties":false},"value":{"description":"Current stored value for this field on this device, or null when unset. For SELECT / MULTI_SELECT the value is the option id (or array of ids). For CHECKBOX it is a boolean. For DATE it is an ISO date string.","anyOf":[{"type":"boolean"},{"type":"number"},{"type":"string"},{"type":"array","items":{"type":"string"}},{"type":"null"}]}},"required":["field","value"],"additionalProperties":false},"SearchDevicesBody":{"type":"object","properties":{"filter":{"description":"One entry per criterion, keyed by the `key` returned by the filter catalog (`GET /devices/filters-options`) — a native key such as `platform`, `availableStatus`, `assigned` or `mdmStatuses.online`, or a custom field id. Every value is a clause { operationType, values } — never a bare value, never an operator like `eq`. `availableStatus` takes only IN_USE, IN_STOCK, RETIRED. Whether a device has an owner is `assigned` (true or false), never a status. Enrollment is `mdmStatus`: MDM_ON is enrolled, MDM_OFF, MISSING_AGENT, READY_ZTD and MDM_ON_IN_ANOTHER_MDM are the other states. A device name, serial number or IMEI goes in `search`. The device type is not a criterion: read `type` on the returned devices. An unknown key is rejected with 400 rather than ignored. Illustrative filters: devices free to hand out → `{\"availableStatus\":{\"operationType\":\"INCLUDE\",\"values\":[\"IN_STOCK\"]},\"assigned\":{\"operationType\":\"INCLUDE\",\"values\":[false]}}`; devices offline for a week or more → `{\"mdmStatuses.online\":{\"operationType\":\"INCLUDE\",\"values\":[\"INACTIVE\"]}}`; macOS in use → `{\"platform\":{\"operationType\":\"INCLUDE\",\"values\":[\"MACOS\"]},\"availableStatus\":{\"operationType\":\"INCLUDE\",\"values\":[\"IN_USE\"]}}`; a custom field value → `{\"<customFieldId>\":{\"operationType\":\"INCLUDE\",\"values\":[\"<optionId>\"]}}`.","type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"object","properties":{"operationType":{"description":"INCLUDE keeps the devices matching the values, EXCLUDE keeps the devices that do not.","type":"string","enum":["INCLUDE","EXCLUDE"]},"values":{"description":"Values to match, always as an array — take them from the criterion `values` in the filter catalog. Booleans are accepted for flag criteria.","minItems":1,"type":"array","items":{"anyOf":[{"type":"string"},{"type":"boolean"}]}}},"required":["operationType","values"]}},"matchAny":{"description":"When true, a device matching ANY clause is returned (OR). Omitted or false means every clause must match (AND).","type":"boolean"},"search":{"description":"Free-text search over device name, serial number, IMEI, owner and custom field values.","type":"string"},"page":{"default":1,"type":"integer","minimum":1,"maximum":9007199254740991},"perPage":{"description":"Devices per page (default 25, max 100). Device payloads are large — keep pages small.","default":25,"type":"integer","minimum":1,"maximum":100}}},"SearchDevices_Output":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"ownerId":{"description":"The ID of the employee assigned to this device","anyOf":[{"type":"string"},{"type":"null"}]},"name":{"anyOf":[{"type":"string"},{"type":"null"}]},"serialNumber":{"anyOf":[{"type":"string"},{"type":"null"}]},"computerName":{"description":"**Deprecated** — use `name` instead. This field will be removed on 2026-04-13.","deprecated":true,"anyOf":[{"type":"string"},{"type":"null"}]},"tags":{"type":"array","items":{"type":"string"}},"type":{"anyOf":[{"type":"string","enum":["LAPTOP","DESKTOP","TABLET","SMARTPHONE"]},{"type":"null"}]},"condition":{"description":"Physical condition recorded for the device","anyOf":[{"type":"string","enum":["BROKEN","FAIR","GOOD","EXCELLENT"]},{"type":"null"}]},"platform":{"anyOf":[{"type":"string","enum":["ANDROID","IOS","MACOS","WINDOWS","LINUX","CHROME_OS","IPADOS","UNKNOWN"]},{"type":"null"}]},"brand":{"anyOf":[{"type":"string"},{"type":"null"}]},"manufacturer":{"anyOf":[{"type":"string"},{"type":"null"}]},"modelName":{"anyOf":[{"type":"string"},{"type":"null"}]},"modelIdentifier":{"anyOf":[{"type":"string"},{"type":"null"}]},"year":{"anyOf":[{"type":"number"},{"type":"null"}]},"osVersion":{"anyOf":[{"type":"string"},{"type":"null"}]},"osName":{"anyOf":[{"type":"string"},{"type":"null"}]},"buildVersion":{"anyOf":[{"type":"string"},{"type":"null"}]},"osUpdateStatus":{"description":"OS update status of the device against the company's OS update policies: UP_TO_DATE, NOT_UP_TO_DATE, or NOT_SETUP when no OS update policy targets the device. Null when unknown.","anyOf":[{"type":"string","enum":["UP_TO_DATE","NOT_UP_TO_DATE","NOT_SETUP"]},{"type":"null"}]},"isEnrolled":{"type":"boolean"},"enrolledAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"disenrolledAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"purchaseDate":{"description":"Date the device was purchased","anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"decommissioningDate":{"description":"Date the device was decommissioned","anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"purchasePriceNoVAT":{"description":"Purchase price excluding VAT, in cents","anyOf":[{"anyOf":[{"type":"number"},{"type":"null"}]},{"type":"null"}]},"lockWipeStatus":{"description":"Current lock/wipe status of the device. LOCKING/LOCKED for lock operations, UNLOCKING for unlock in progress, WIPING/WIPED for wipe operations. Null when device is in normal state.","anyOf":[{"type":"string","enum":["LOCKED","LOCKING","UNLOCKING","WIPED","WIPING"]},{"type":"null"}]},"edrProvider":{"description":"EDR provider protecting the device: SENTINELONE, THREATDOWN, or null when no EDR (e.g. no EDR configured, or device not yet protected).","anyOf":[{"type":"string","enum":["SENTINELONE","THREATDOWN"]},{"type":"null"}]},"connectionStatus":{"description":"Device liveness: ONLINE (currently reachable), OFFLINE (not reachable but its agent is still live), INACTIVE (the agent stopped reporting — in practice no news for about a week), NOT_COMPATIBLE (iOS, iPadOS and Android have no liveness notion), or null when MDM is off for the device. INACTIVE follows from the agent being disabled, NOT from a threshold on `lastSeenAt` — to find devices silent for months, read `lastSeenAt`.","anyOf":[{"type":"string","enum":["ONLINE","OFFLINE","INACTIVE","NOT_COMPATIBLE"]},{"type":"null"}]},"lastSeenAt":{"description":"Last time the platform received anything from the device. The field to use for \"silent for N days\".","anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"lastScannedAt":{"description":"Last time the device's inventory was collected. A device can be heard from without being re-scanned.","anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"lastRestartAt":{"description":"Last time the device rebooted","anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"availableStatus":{"description":"Fleet-management status of the device: IN_USE, IN_STOCK or RETIRED","anyOf":[{"type":"string","enum":["IN_USE","IN_STOCK","RETIRED"]},{"type":"null"}]},"enrollmentType":{"description":"How the device was enrolled into MDM","anyOf":[{"type":"string","enum":["MANUAL","AUTOMATIC"]},{"type":"null"}]},"assetId":{"description":"Asset tag recorded by the company","anyOf":[{"type":"string"},{"type":"null"}]},"privateIpAddress":{"anyOf":[{"type":"string"},{"type":"null"}]},"publicIpAddress":{"anyOf":[{"type":"string"},{"type":"null"}]},"ram":{"description":"RAM in GB","anyOf":[{"type":"number"},{"type":"null"}]},"storage":{"description":"Disk size in GB","anyOf":[{"type":"number"},{"type":"null"}]},"processor":{"description":"Processor name, e.g. \"Apple M2 Pro\"","anyOf":[{"type":"string"},{"type":"null"}]},"cpuType":{"description":"Raw CPU type reported by the device, e.g. \"arm64e\" or \"x86_64\"","anyOf":[{"type":"string"},{"type":"null"}]},"cpuArchitecture":{"description":"CPU instruction-set architecture, derived from the device CPU. Use it to tell which architecture-specific software build a device can run. Null when the device has never been synced.","anyOf":[{"type":"string","enum":["ARM","X86"]},{"type":"null"}]},"inchScreenSize":{"description":"Screen size in inches","anyOf":[{"type":"number"},{"type":"null"}]},"keyboardLayout":{"anyOf":[{"type":"string","enum":["FRENCH","US_ENGLISH","ARABIC","CHINESE_PINYIN","CHINESE_ZHUYIN","DANISH","DUTCH","GERMAN","INTERNATIONAL_ENGLISH","ITALIAN","NORWEGIAN","PORTUGUESE","RUSSIAN","SPANISH","SPANISH_LATIN_AMERICA","SWEDISH","SWISS","TURKISH","UK_ENGLISH","UKRAINIAN","HEBREW","MACEDONIAN","JAPANESE_JIS"]},{"type":"null"}]},"batteryHealth":{"description":"Battery condition reported by the device: NORMAL, or SERVICE_RECOMMENDED when the battery should be serviced. Null when the device reported nothing.","anyOf":[{"type":"string","enum":["SERVICE_RECOMMENDED","NORMAL"]},{"type":"null"}]},"batteryCycleCount":{"anyOf":[{"type":"number"},{"type":"null"}]},"diskSpaceAvailableStatus":{"description":"Bucketed free-disk-space level derived from percentDiskSpaceAvailable","anyOf":[{"type":"string","enum":["LOW","MEDIUM","HIGH"]},{"type":"null"}]},"percentDiskSpaceAvailable":{"anyOf":[{"type":"number"},{"type":"null"}]},"encrypted":{"description":"Whether the device disk is encrypted. Null means the device reported nothing about encryption — not that it is unencrypted. To count the unencrypted fleet, read `false`; to size the blind spot, read `null`.","anyOf":[{"type":"boolean"},{"type":"null"}]},"encryptedAt":{"description":"First time the device was seen encrypted","anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"bootstrapTokenEscrowed":{"description":"Whether the macOS bootstrap token is escrowed. Null when the device reported nothing about it.","anyOf":[{"type":"boolean"},{"type":"null"}]},"bootstrapTokenEscrowedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","tags","isEnrolled","createdAt","updatedAt"],"additionalProperties":false}},"pagination":{"type":"object","properties":{"totalElements":{"type":"integer","minimum":0,"maximum":9007199254740991},"totalPages":{"type":"integer","minimum":0,"maximum":9007199254740991},"page":{"type":"integer","minimum":1,"maximum":9007199254740991},"perPage":{"type":"integer","minimum":1,"maximum":100}},"required":["totalElements","totalPages","page","perPage"],"additionalProperties":false}},"required":["data","pagination"],"additionalProperties":false},"CountDevicesBody":{"type":"object","properties":{"queries":{"description":"Up to 20 device queries, each under a label you choose (letters, digits, \"_\" or \"-\"), e.g. `{\"mdmOff\":{\"filter\":{\"mdmStatus\":{\"operationType\":\"INCLUDE\",\"values\":[\"MDM_OFF\"]}}},\"all\":{}}`. A query takes the `filter`, `matchAny` and `search` of `getDevices`, nothing else.","type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"object","properties":{"filter":{"description":"One entry per criterion, keyed by the `key` returned by the filter catalog (`GET /devices/filters-options`) — a native key such as `platform`, `availableStatus`, `assigned` or `mdmStatuses.online`, or a custom field id. Every value is a clause { operationType, values } — never a bare value, never an operator like `eq`. `availableStatus` takes only IN_USE, IN_STOCK, RETIRED. Whether a device has an owner is `assigned` (true or false), never a status. Enrollment is `mdmStatus`: MDM_ON is enrolled, MDM_OFF, MISSING_AGENT, READY_ZTD and MDM_ON_IN_ANOTHER_MDM are the other states. A device name, serial number or IMEI goes in `search`. The device type is not a criterion: read `type` on the returned devices. An unknown key is rejected with 400 rather than ignored. Illustrative filters: devices free to hand out → `{\"availableStatus\":{\"operationType\":\"INCLUDE\",\"values\":[\"IN_STOCK\"]},\"assigned\":{\"operationType\":\"INCLUDE\",\"values\":[false]}}`; devices offline for a week or more → `{\"mdmStatuses.online\":{\"operationType\":\"INCLUDE\",\"values\":[\"INACTIVE\"]}}`; macOS in use → `{\"platform\":{\"operationType\":\"INCLUDE\",\"values\":[\"MACOS\"]},\"availableStatus\":{\"operationType\":\"INCLUDE\",\"values\":[\"IN_USE\"]}}`; a custom field value → `{\"<customFieldId>\":{\"operationType\":\"INCLUDE\",\"values\":[\"<optionId>\"]}}`.","type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"object","properties":{"operationType":{"description":"INCLUDE keeps the devices matching the values, EXCLUDE keeps the devices that do not.","type":"string","enum":["INCLUDE","EXCLUDE"]},"values":{"description":"Values to match, always as an array — take them from the criterion `values` in the filter catalog. Booleans are accepted for flag criteria.","minItems":1,"type":"array","items":{"anyOf":[{"type":"string"},{"type":"boolean"}]}}},"required":["operationType","values"]}},"matchAny":{"description":"When true, a device matching ANY clause is returned (OR). Omitted or false means every clause must match (AND).","type":"boolean"},"search":{"description":"Free-text search over device name, serial number, IMEI, owner and custom field values.","type":"string"}},"additionalProperties":false}}},"required":["queries"]},"CountDevices_Output":{"type":"object","properties":{"counts":{"type":"object","description":"The number of records matching each query, under the label the query was sent with","propertyNames":{"type":"string"},"additionalProperties":{"type":"integer","minimum":0,"maximum":9007199254740991}}},"required":["counts"],"additionalProperties":false},"SetDeviceCustomFieldValuesBatchBody":{"type":"object","properties":{"items":{"description":"Custom field value writes to apply. Each item targets one (deviceId, customFieldId) pair, which must be unique within the batch. Up to 100 items per call. Writes are best-effort: inspect the per-item `results` to learn which succeeded — the HTTP status is 200 even when some items fail.","minItems":1,"maxItems":100,"type":"array","items":{"type":"object","properties":{"deviceId":{"description":"Device id to write the value to.","type":"string"},"customFieldId":{"description":"CustomField id (MongoDB ObjectId string) to write.","type":"string"},"value":{"description":"Value to set. Must conform to the field type. Pass null to clear an existing value. For SELECT supply the option id (string). For MULTI_SELECT supply an array of option ids.","anyOf":[{"type":"boolean"},{"type":"number"},{"type":"string"},{"type":"array","items":{"type":"string"}},{"type":"null"}]}},"required":["deviceId","customFieldId","value"]}}},"required":["items"]},"SetDeviceCustomFieldValuesBatchResult_Output":{"type":"object","properties":{"successCount":{"type":"integer","description":"Number of items written successfully.","minimum":-9007199254740991,"maximum":9007199254740991},"failureCount":{"type":"integer","description":"Number of items that failed.","minimum":-9007199254740991,"maximum":9007199254740991},"results":{"type":"array","description":"Per-item outcome, in the same order as the input `items`.","items":{"type":"object","properties":{"deviceId":{"type":"string"},"customFieldId":{"type":"string"},"status":{"type":"string","enum":["ok","error"]},"errorCode":{"description":"Machine-readable error code when status is \"error\".","anyOf":[{"type":"string"},{"type":"null"}]},"message":{"description":"Human-readable error detail when status is \"error\".","anyOf":[{"type":"string"},{"type":"null"}]}},"required":["deviceId","customFieldId","status"],"additionalProperties":false}}},"required":["successCount","failureCount","results"],"additionalProperties":false},"GetDeviceSoftware_Output":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"softwareId":{"type":"string"},"name":{"type":"string"},"iconUrl":{"anyOf":[{"type":"string"},{"type":"null"}]},"status":{"type":"string","enum":["installed","failed","in_progress","not_installed"]},"installedVersion":{"anyOf":[{"type":"string"},{"type":"null"}]},"availableVersion":{"anyOf":[{"type":"string"},{"type":"null"}]},"actions":{"type":"object","properties":{"primaryAction":{"description":"The install/update action offered for this software on this device","type":"string","enum":["install","update"]},"canRunPrimaryAction":{"description":"Whether the primary action can currently run on this device","type":"boolean"},"primaryActionDisabledReason":{"description":"Why the primary action is unavailable, when it is","anyOf":[{"type":"string","enum":["in_progress","host_scripts_disabled","host_not_mdm_enrolled"]},{"type":"null"}]},"canUninstall":{"description":"Whether this software can be uninstalled from this device","type":"boolean"}},"required":["primaryAction","canRunPrimaryAction","primaryActionDisabledReason","canUninstall"],"additionalProperties":false}},"required":["softwareId","name","iconUrl","status","installedVersion","availableVersion","actions"],"additionalProperties":false}},"pagination":{"type":"object","properties":{"totalElements":{"type":"integer","minimum":0,"maximum":9007199254740991},"totalPages":{"type":"integer","minimum":0,"maximum":9007199254740991},"page":{"type":"integer","minimum":1,"maximum":9007199254740991},"perPage":{"type":"integer","minimum":1,"maximum":100}},"required":["totalElements","totalPages","page","perPage"],"additionalProperties":false},"isDeviceOnline":{"type":"boolean"}},"required":["data","pagination","isDeviceOnline"],"additionalProperties":false},"GetDeviceMdmControls_Output":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"type":{"type":"string","enum":["malwarebyte_macos","malwarebyte_windows","malwarebyte_linux","recoveryOs_macos","softwareUpdate_macos","appBlocking_macos","wifi_macos","wifi_ios","wifi_ipados","wifi_windows","wifi_android","wifi_linux","adminUserManagement_macos","adminUserManagement_windows","adminUserPasswordRotation_macos","adminUserPasswordRotation_windows","deviceNaming_macos","deviceNaming_windows","deviceNaming_linux","googleChrome_macos","googleChrome_windows","firewall_macos","firewall_windows","usbBlocking_macos","usbBlocking_windows","usbBlocking_linux","usbBlocking_android","entraSSO_macos","oktaSSO_macos","primoSSO_macos","customFile_macos","customFile_ios","customFile_ipados","customFile_windows","customFile_android","customFile_linux","passwordPolicy_macos","passwordPolicy_windows","passwordPolicy_ios","passwordPolicy_ipados","passwordPolicy_android","sentinelOne_macos","sentinelOne_windows","sentinelOne_windows_arm64","sentinelOne_linux_deb","sentinelOne_linux_deb_arm64","sentinelOne_linux_rpm","sentinelOne_linux_rpm_arm64","diskEncryption_all","osUpdate_macos","osUpdate_windows","osUpdate_ios","osUpdate_ipados","rustdesk_macos","rustdesk_windows","disableProfilesPane_macos","screenCapture_macos","disableAirdrop_macos","airPrint_macos","webClip_macos","webClip_ios","webClip_ipados"]},"platform":{"type":"string","enum":["macos","windows","ios","ipados","android","linux","chromeos","unknown"]},"tags":{"type":"array","items":{"type":"string"}},"targetMethod":{"description":"How the control reaches this device: All (every device), DeviceGroup, or CustomTarget","type":"string","enum":["All","DeviceGroup","CustomTarget"]}},"required":["id","name","type","platform","tags","targetMethod"],"additionalProperties":false}}},"required":["data"],"additionalProperties":false},"GetSoftwareInstallLogs_Output":{"type":"object","properties":{"status":{"anyOf":[{"type":"string","enum":["installed","pending_install","failed_install","no_install_attempt","logs_unavailable"]},{"type":"null"}]},"attempts":{"type":"array","items":{"type":"object","properties":{"status":{"anyOf":[{"type":"string","enum":["installed","pending_install","failed_install"]},{"type":"null"}]},"ranAt":{"type":"string"},"trigger":{"type":"string","enum":["manual","selfService","policy","setupExperience"]},"policyName":{"anyOf":[{"type":"string"},{"type":"null"}]},"output":{"anyOf":[{"type":"string"},{"type":"null"}]},"preInstallQueryOutput":{"anyOf":[{"type":"string"},{"type":"null"}]},"postInstallScriptOutput":{"anyOf":[{"type":"string"},{"type":"null"}]},"failureReason":{"anyOf":[{"type":"string"},{"type":"null"}]},"skippedInstall":{"type":"boolean"}},"required":["status","ranAt","trigger","policyName","output","preInstallQueryOutput","postInstallScriptOutput","failureReason","skippedInstall"],"additionalProperties":false}}},"required":["status","attempts"],"additionalProperties":false},"DeviceSoftwareActionResult_Output":{"type":"object","properties":{"success":{"type":"boolean","const":true},"message":{"type":"string","description":"A human-readable description of the action"}},"required":["success","message"],"additionalProperties":false},"GetDeviceActivities_Output":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"uuid":{"anyOf":[{"type":"string"},{"type":"null"}]},"activityType":{"type":"string"},"actorFullName":{"anyOf":[{"type":"string"},{"type":"null"}]},"actorId":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"actorGravatar":{"anyOf":[{"type":"string"},{"type":"null"}]},"actorEmail":{"anyOf":[{"type":"string"},{"type":"null"}]},"createdAt":{"type":"string"},"fleetInitiated":{"anyOf":[{"type":"boolean"},{"type":"null"}]},"details":{"anyOf":[{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},{"type":"null"}]}},"required":["id","uuid","activityType","createdAt","fleetInitiated","details"],"additionalProperties":false}},"pagination":{"type":"object","properties":{"page":{"type":"integer","minimum":1,"maximum":9007199254740991},"perPage":{"type":"integer","minimum":1,"maximum":100},"hasNextPage":{"type":"boolean"},"hasPreviousPage":{"type":"boolean"},"totalElements":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]}},"required":["page","perPage","hasNextPage","hasPreviousPage","totalElements"],"additionalProperties":false}},"required":["data","pagination"],"additionalProperties":false},"GetDeviceUpcomingActivities_Output":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"uuid":{"anyOf":[{"type":"string"},{"type":"null"}]},"activityType":{"type":"string"},"actorFullName":{"anyOf":[{"type":"string"},{"type":"null"}]},"actorId":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"actorGravatar":{"anyOf":[{"type":"string"},{"type":"null"}]},"actorEmail":{"anyOf":[{"type":"string"},{"type":"null"}]},"createdAt":{"type":"string"},"fleetInitiated":{"anyOf":[{"type":"boolean"},{"type":"null"}]},"details":{"anyOf":[{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},{"type":"null"}]}},"required":["id","uuid","activityType","createdAt","fleetInitiated","details"],"additionalProperties":false}},"pagination":{"type":"object","properties":{"page":{"type":"integer","minimum":1,"maximum":9007199254740991},"perPage":{"type":"integer","minimum":1,"maximum":100},"hasNextPage":{"type":"boolean"},"hasPreviousPage":{"type":"boolean"},"totalElements":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]}},"required":["page","perPage","hasNextPage","hasPreviousPage","totalElements"],"additionalProperties":false}},"required":["data","pagination"],"additionalProperties":false},"DeviceActionResult_Output":{"type":"object","properties":{"success":{"type":"boolean","const":true},"message":{"type":"string","description":"A human-readable description of the action"}},"required":["success","message"],"additionalProperties":false},"ResendDeviceProfileResult_Output":{"type":"object","properties":{"success":{"type":"boolean","const":true},"profileFleetId":{"type":"string","description":"Identifier of the configuration profile that was resent"},"statusBeforeResend":{"type":"string","description":"Delivery status of the profile on the device just before the resend was requested","enum":["verified","verifying","pending","failed"]},"message":{"type":"string","description":"A human-readable description of the action"}},"required":["success","profileFleetId","statusBeforeResend","message"],"additionalProperties":false},"GetDeviceCommands_Output":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"hostUuid":{"type":"string"},"commandUuid":{"type":"string"},"status":{"type":"string"},"commandStatus":{"anyOf":[{"type":"string"},{"type":"null"}]},"updatedAt":{"type":"string"},"requestType":{"type":"string"},"name":{"anyOf":[{"type":"string"},{"type":"null"}]},"hostname":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["hostUuid","commandUuid","status","commandStatus","updatedAt","requestType","name","hostname"],"additionalProperties":false}},"pagination":{"type":"object","properties":{"page":{"type":"integer","minimum":1,"maximum":9007199254740991},"perPage":{"type":"integer","minimum":1,"maximum":100},"hasNextPage":{"type":"boolean"},"hasPreviousPage":{"type":"boolean"},"totalElements":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]}},"required":["page","perPage","hasNextPage","hasPreviousPage","totalElements"],"additionalProperties":false}},"required":["data","pagination"],"additionalProperties":false},"GetDeviceCommandResults_Output":{"type":"object","properties":{"results":{"type":"array","items":{"type":"object","properties":{"commandUuid":{"type":"string"},"status":{"type":"string"},"updatedAt":{"type":"string"},"requestType":{"type":"string"},"hostname":{"anyOf":[{"type":"string"},{"type":"null"}]},"payload":{"anyOf":[{"type":"string"},{"type":"null"}]},"result":{"anyOf":[{"type":"string"},{"type":"null"}]},"resultsMetadata":{"anyOf":[{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},{"type":"null"}]}},"required":["commandUuid","status","updatedAt","requestType","hostname","payload","result","resultsMetadata"],"additionalProperties":false}}},"required":["results"],"additionalProperties":false},"GetScripts_Output":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"description":"Identifier of the saved script, used as `scriptId` when running it.","type":"number"},"name":{"description":"File name of the script. Its extension decides the interpreter and therefore the platforms: `.sh` (shell, macOS + Linux), `.py` (Python, macOS + Linux), `.ps1` (PowerShell, Windows).","type":"string"},"platforms":{"description":"Platforms this script can run on, derived from its name.","type":"array","items":{"type":"string","enum":["macos","windows","linux"]}},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","name","platforms","createdAt","updatedAt"],"additionalProperties":false}}},"required":["data"],"additionalProperties":false},"GetScriptRuns_Output":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"script":{"type":"object","properties":{"scriptId":{"description":"Saved script that was run, or null when the contents were sent inline.","anyOf":[{"type":"number"},{"type":"null"}]},"name":{"description":"Script name at the time of the run. Null for an inline run.","anyOf":[{"type":"string"},{"type":"null"}]}},"required":["scriptId","name"],"additionalProperties":false},"target":{"description":"The target as recorded, with group and device names resolved.","anyOf":[{"type":"object","properties":{"type":{"type":"string","const":"all"}},"required":["type"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"deviceGroups"},"deviceGroups":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["id","name"],"additionalProperties":false}}},"required":["type","deviceGroups"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"devices"},"devices":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"anyOf":[{"type":"string"},{"type":"null"}]},"platform":{"type":"string"}},"required":["id","name","platform"],"additionalProperties":false}}},"required":["type","devices"],"additionalProperties":false}]},"platforms":{"type":"array","items":{"type":"string","enum":["macos","windows","linux"]}},"initiator":{"description":"Who triggered the run — a user name, or the name of the API key that called this endpoint.","anyOf":[{"type":"string"},{"type":"null"}]},"statusCounts":{"description":"Number of executions in each status.","type":"object","properties":{"pending":{"type":"number"},"success":{"type":"number"},"failed":{"type":"number"},"not_run":{"type":"number"},"timeout":{"type":"number"},"cancelled":{"type":"number"}},"required":["pending","success","failed","not_run","timeout","cancelled"],"additionalProperties":false},"totalExecutions":{"description":"Number of devices the run resolved to.","type":"number"},"status":{"description":"Overall state, derived from the executions: `running` while any is still pending.","type":"string","enum":["running","success","failed","cancelled"]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","script","target","platforms","initiator","statusCounts","totalExecutions","status","createdAt"],"additionalProperties":false}},"pagination":{"type":"object","properties":{"totalElements":{"type":"integer","minimum":0,"maximum":9007199254740991},"totalPages":{"type":"integer","minimum":0,"maximum":9007199254740991},"page":{"type":"integer","minimum":1,"maximum":9007199254740991},"perPage":{"type":"integer","minimum":1,"maximum":100}},"required":["totalElements","totalPages","page","perPage"],"additionalProperties":false}},"required":["data","pagination"],"additionalProperties":false},"PreviewScriptRunTargetBody":{"type":"object","properties":{"target":{"description":"Which devices to run on, intersected with `platforms`. Resolved once at trigger time — devices joining a group later are not included.","anyOf":[{"type":"object","properties":{"type":{"type":"string","const":"all"}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","const":"deviceGroups"},"deviceGroupIds":{"minItems":1,"type":"array","items":{"type":"string"}}},"required":["type","deviceGroupIds"]},{"type":"object","properties":{"type":{"type":"string","const":"devices"},"deviceIds":{"minItems":1,"type":"array","items":{"type":"string"}}},"required":["type","deviceIds"]}]},"platforms":{"description":"Platforms to run on. The target is intersected with this list, and a saved script must support them.","minItems":1,"type":"array","items":{"type":"string","enum":["macos","windows","linux"]}}},"required":["target","platforms"]},"PreviewScriptRunTarget_Output":{"type":"object","properties":{"count":{"type":"number","description":"Number of devices a run with this target and these platforms would reach."}},"required":["count"],"additionalProperties":false},"RunScriptBody":{"type":"object","properties":{"script":{"description":"What to run: `{ \"scriptId\": 12 }` for a script from the catalog, or `{ \"contents\": \"...\" }` to send the source inline. An inline run may only target a single device.","anyOf":[{"type":"object","properties":{"scriptId":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991}},"required":["scriptId"]},{"type":"object","properties":{"contents":{"type":"string","minLength":1,"maxLength":10000}},"required":["contents"]}]},"target":{"description":"Which devices to run on, intersected with `platforms`. Resolved once at trigger time — devices joining a group later are not included.","anyOf":[{"type":"object","properties":{"type":{"type":"string","const":"all"}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","const":"deviceGroups"},"deviceGroupIds":{"minItems":1,"type":"array","items":{"type":"string"}}},"required":["type","deviceGroupIds"]},{"type":"object","properties":{"type":{"type":"string","const":"devices"},"deviceIds":{"minItems":1,"type":"array","items":{"type":"string"}}},"required":["type","deviceIds"]}]},"platforms":{"description":"Platforms to run on. The target is intersected with this list, and a saved script must support them.","minItems":1,"type":"array","items":{"type":"string","enum":["macos","windows","linux"]}}},"required":["script","target","platforms"]},"GetScriptRunExecutions_Output":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"runId":{"description":"Identifier of the script run this execution belongs to.","type":"string"},"deviceId":{"type":"string"},"device":{"description":"Resolved device, null if it no longer exists.","anyOf":[{"type":"object","properties":{"id":{"type":"string"},"name":{"anyOf":[{"type":"string"},{"type":"null"}]},"serialNumber":{"anyOf":[{"type":"string"},{"type":"null"}]},"platform":{"type":"string"}},"required":["id","name","serialNumber","platform"],"additionalProperties":false},{"type":"null"}]},"status":{"description":"Outcome on one device. `pending`: queued, the device may be offline. `success`: ran with exit code 0. `failed`: ran and exited with a non-zero code. `not_run`: the device never started the script — read `message` for the reason (missing interpreter, incompatible host, host outside the Fleet team). `timeout`: exceeded the execution limit, or the device reported nothing within 24 hours. `cancelled`: cancelled before running.","type":"string","enum":["pending","success","failed","not_run","timeout","cancelled"]},"output":{"description":"Combined stdout/stderr once the execution completes. Null while pending.","anyOf":[{"type":"string"},{"type":"null"}]},"message":{"description":"Diagnostic reported by the MDM when the script did not run or did not complete. Null otherwise.","anyOf":[{"type":"string"},{"type":"null"}]},"exitCode":{"description":"Process exit code once the execution completes. Null while pending.","anyOf":[{"type":"number"},{"type":"null"}]},"runtime":{"description":"Duration in seconds once the execution completes. Null while pending.","anyOf":[{"type":"number"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","runId","deviceId","device","status","output","message","exitCode","runtime","createdAt","updatedAt"],"additionalProperties":false}},"pagination":{"type":"object","properties":{"totalElements":{"type":"integer","minimum":0,"maximum":9007199254740991},"totalPages":{"type":"integer","minimum":0,"maximum":9007199254740991},"page":{"type":"integer","minimum":1,"maximum":9007199254740991},"perPage":{"type":"integer","minimum":1,"maximum":100}},"required":["totalElements","totalPages","page","perPage"],"additionalProperties":false}},"required":["data","pagination"],"additionalProperties":false},"GetScriptRun_Output":{"type":"object","properties":{"id":{"type":"string"},"script":{"type":"object","properties":{"scriptId":{"description":"Saved script that was run, or null when the contents were sent inline.","anyOf":[{"type":"number"},{"type":"null"}]},"name":{"description":"Script name at the time of the run. Null for an inline run.","anyOf":[{"type":"string"},{"type":"null"}]}},"required":["scriptId","name"],"additionalProperties":false},"target":{"description":"The target as recorded, with group and device names resolved.","anyOf":[{"type":"object","properties":{"type":{"type":"string","const":"all"}},"required":["type"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"deviceGroups"},"deviceGroups":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["id","name"],"additionalProperties":false}}},"required":["type","deviceGroups"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"devices"},"devices":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"anyOf":[{"type":"string"},{"type":"null"}]},"platform":{"type":"string"}},"required":["id","name","platform"],"additionalProperties":false}}},"required":["type","devices"],"additionalProperties":false}]},"platforms":{"type":"array","items":{"type":"string","enum":["macos","windows","linux"]}},"initiator":{"description":"Who triggered the run — a user name, or the name of the API key that called this endpoint.","anyOf":[{"type":"string"},{"type":"null"}]},"statusCounts":{"type":"object","description":"Number of executions in each status.","properties":{"pending":{"type":"number"},"success":{"type":"number"},"failed":{"type":"number"},"not_run":{"type":"number"},"timeout":{"type":"number"},"cancelled":{"type":"number"}},"required":["pending","success","failed","not_run","timeout","cancelled"],"additionalProperties":false},"totalExecutions":{"type":"number","description":"Number of devices the run resolved to."},"status":{"type":"string","description":"Overall state, derived from the executions: `running` while any is still pending.","enum":["running","success","failed","cancelled"]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"contents":{"type":"string","description":"Full source of the script as executed, kept even if the script later changes."}},"required":["id","script","target","platforms","initiator","statusCounts","totalExecutions","status","createdAt","contents"],"additionalProperties":false},"GetScript_Output":{"type":"object","properties":{"id":{"type":"number","description":"Identifier of the saved script, used as `scriptId` when running it."},"name":{"type":"string","description":"File name of the script. Its extension decides the interpreter and therefore the platforms: `.sh` (shell, macOS + Linux), `.py` (Python, macOS + Linux), `.ps1` (PowerShell, Windows)."},"platforms":{"type":"array","description":"Platforms this script can run on, derived from its name.","items":{"type":"string","enum":["macos","windows","linux"]}},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"contents":{"type":"string","description":"Full source of the script."}},"required":["id","name","platforms","createdAt","updatedAt","contents"],"additionalProperties":false},"GetMdmControls_Output":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"type":{"type":"string","enum":["malwarebyte_macos","malwarebyte_windows","malwarebyte_linux","recoveryOs_macos","softwareUpdate_macos","appBlocking_macos","wifi_macos","wifi_ios","wifi_ipados","wifi_windows","wifi_android","wifi_linux","adminUserManagement_macos","adminUserManagement_windows","adminUserPasswordRotation_macos","adminUserPasswordRotation_windows","deviceNaming_macos","deviceNaming_windows","deviceNaming_linux","googleChrome_macos","googleChrome_windows","firewall_macos","firewall_windows","usbBlocking_macos","usbBlocking_windows","usbBlocking_linux","usbBlocking_android","entraSSO_macos","oktaSSO_macos","primoSSO_macos","customFile_macos","customFile_ios","customFile_ipados","customFile_windows","customFile_android","customFile_linux","passwordPolicy_macos","passwordPolicy_windows","passwordPolicy_ios","passwordPolicy_ipados","passwordPolicy_android","sentinelOne_macos","sentinelOne_windows","sentinelOne_windows_arm64","sentinelOne_linux_deb","sentinelOne_linux_deb_arm64","sentinelOne_linux_rpm","sentinelOne_linux_rpm_arm64","diskEncryption_all","osUpdate_macos","osUpdate_windows","osUpdate_ios","osUpdate_ipados","rustdesk_macos","rustdesk_windows","disableProfilesPane_macos","screenCapture_macos","disableAirdrop_macos","airPrint_macos","webClip_macos","webClip_ios","webClip_ipados"]},"platform":{"type":"string","enum":["macos","windows","ios","ipados","android","linux","chromeos","unknown"]},"tags":{"type":"array","items":{"type":"string"}},"enabled":{"type":"boolean"},"targetMethod":{"type":"string","enum":["All","DeviceGroup","CustomTarget"]}},"required":["id","name","type","platform","tags","enabled","targetMethod"],"additionalProperties":false}},"pagination":{"type":"object","properties":{"totalElements":{"type":"integer","minimum":0,"maximum":9007199254740991},"totalPages":{"type":"integer","minimum":0,"maximum":9007199254740991},"page":{"type":"integer","minimum":1,"maximum":9007199254740991},"perPage":{"type":"integer","minimum":1,"maximum":100}},"required":["totalElements","totalPages","page","perPage"],"additionalProperties":false}},"required":["data","pagination"],"additionalProperties":false},"GetMdmControlCatalog_Output":{"type":"object","properties":{"catalog":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","enum":["malwarebyte_macos","malwarebyte_windows","malwarebyte_linux","recoveryOs_macos","softwareUpdate_macos","appBlocking_macos","wifi_macos","wifi_ios","wifi_ipados","wifi_windows","wifi_android","wifi_linux","adminUserManagement_macos","adminUserManagement_windows","adminUserPasswordRotation_macos","adminUserPasswordRotation_windows","deviceNaming_macos","deviceNaming_windows","deviceNaming_linux","googleChrome_macos","googleChrome_windows","firewall_macos","firewall_windows","usbBlocking_macos","usbBlocking_windows","usbBlocking_linux","usbBlocking_android","entraSSO_macos","oktaSSO_macos","primoSSO_macos","customFile_macos","customFile_ios","customFile_ipados","customFile_windows","customFile_android","customFile_linux","passwordPolicy_macos","passwordPolicy_windows","passwordPolicy_ios","passwordPolicy_ipados","passwordPolicy_android","sentinelOne_macos","sentinelOne_windows","sentinelOne_windows_arm64","sentinelOne_linux_deb","sentinelOne_linux_deb_arm64","sentinelOne_linux_rpm","sentinelOne_linux_rpm_arm64","diskEncryption_all","osUpdate_macos","osUpdate_windows","osUpdate_ios","osUpdate_ipados","rustdesk_macos","rustdesk_windows","disableProfilesPane_macos","screenCapture_macos","disableAirdrop_macos","airPrint_macos","webClip_macos","webClip_ios","webClip_ipados"]},"name":{"type":"string"},"description":{"type":"string"},"platform":{"type":"string","enum":["macos","windows","ios","ipados","android","linux","chromeos","unknown"]},"category":{"type":"string","enum":["malwarebytes","recoveryOs","encryption","osUpdate","softwareUpdate","wifi","adminUserManagement","adminUserPasswordRotation","deviceNaming","googleChrome","firewall","usbBlocking","entraSSO","oktaSSO","primoSSO","customFile","passwordPolicy","sentinelOne","rustdesk","appBlocking","disableProfilesPane","disableAirdrop","screenCapture","airPrint","webClip"]},"canBeActivated":{"type":"boolean"},"reasons":{"type":"array","items":{"type":"string","enum":["SHOULD_BE_UNIQUE","SHOULD_SWITCH_TARGET","MISSING_SENTINEL_ONE_INTEGRATION","MISSING_MALWAREBYTES_INTEGRATION","MISSING_ANDROID_MDM_INTEGRATION","MISSING_LINUX_MDM_INTEGRATION","MISSING_APPLE_MDM_INTEGRATION","MISSING_WINDOWS_MDM_INTEGRATION","NO_MDM_INTEGRATION_ENABLED","FEATURE_NOT_ENABLED","MACOS_PASSWORD_POLICY_LOCKED_BY_PLATFORM_SSO","PLATFORM_SSO_OPENID_SHOULD_BE_UNIQUE","PRIMO_DESKTOP_APP_NOT_ENABLED","PRIMO_SSO_CLASSIC_MODE_REMOVED","BOOTSTRAP_PACKAGE_SET_OUTSIDE_PRIMO"]}},"canOnlyHaveGlobalTarget":{"type":"boolean"},"inputSchema":{"description":"JSON Schema for the control config","type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"required":["type","name","description","platform","category","canBeActivated","reasons","canOnlyHaveGlobalTarget","inputSchema"],"additionalProperties":false}}},"required":["catalog"],"additionalProperties":false},"CreateMdmControlBody":{"type":"object","properties":{"type":{"description":"Control type discriminator, e.g. \"wifi_macos\". Discover the creatable types and each type's config JSON Schema via GET /mdm-controls/catalog.","type":"string","enum":["malwarebyte_macos","malwarebyte_windows","malwarebyte_linux","recoveryOs_macos","softwareUpdate_macos","appBlocking_macos","wifi_macos","wifi_ios","wifi_ipados","wifi_windows","wifi_android","wifi_linux","adminUserManagement_macos","adminUserManagement_windows","adminUserPasswordRotation_macos","adminUserPasswordRotation_windows","deviceNaming_macos","deviceNaming_windows","deviceNaming_linux","googleChrome_macos","googleChrome_windows","firewall_macos","firewall_windows","usbBlocking_macos","usbBlocking_windows","usbBlocking_linux","usbBlocking_android","entraSSO_macos","oktaSSO_macos","primoSSO_macos","customFile_macos","customFile_ios","customFile_ipados","customFile_windows","customFile_android","customFile_linux","passwordPolicy_macos","passwordPolicy_windows","passwordPolicy_ios","passwordPolicy_ipados","passwordPolicy_android","sentinelOne_macos","sentinelOne_windows","sentinelOne_windows_arm64","sentinelOne_linux_deb","sentinelOne_linux_deb_arm64","sentinelOne_linux_rpm","sentinelOne_linux_rpm_arm64","diskEncryption_all","osUpdate_macos","osUpdate_windows","osUpdate_ios","osUpdate_ipados","rustdesk_macos","rustdesk_windows","disableProfilesPane_macos","screenCapture_macos","disableAirdrop_macos","airPrint_macos","webClip_macos","webClip_ios","webClip_ipados"]},"name":{"description":"Display name for the control. Omit to use the catalog default name for the given type. Supply a name to create several controls of the same type — some profile-backed types require a unique name.","type":"string","minLength":1},"enabled":{"description":"Whether the control is active once created. Defaults to true when omitted.","type":"boolean"},"configurationPayload":{"description":"Configuration payload for the control, in clear values, matching the type's config JSON Schema (see GET /mdm-controls/catalog). Send null for control types that take no config.","anyOf":[{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},{"type":"null"}]},"targetMethod":{"description":"How the control is targeted. \"All\" targets every device (ignores the group fields below); \"DeviceGroup\" uses the included/excluded group lists.","type":"string","enum":["All","DeviceGroup"]},"includedDeviceGroupIds":{"description":"Device group IDs to include. Used only when targetMethod is \"DeviceGroup\".","type":"array","items":{"type":"string"}},"excludedDeviceGroupIds":{"description":"Device group IDs to exclude. Used only when targetMethod is \"DeviceGroup\".","type":"array","items":{"type":"string"}}},"required":["type","configurationPayload","targetMethod"]},"CreateMdmControl_Output":{"type":"object","properties":{"id":{"type":"string","description":"ID of the created MDM control."}},"required":["id"],"additionalProperties":false},"UpdateMdmControlBody":{"type":"object","properties":{"type":{"description":"Control type discriminator, e.g. \"wifi_macos\". Read it from GET /mdm-controls/:id.","type":"string","enum":["malwarebyte_macos","malwarebyte_windows","malwarebyte_linux","recoveryOs_macos","softwareUpdate_macos","appBlocking_macos","wifi_macos","wifi_ios","wifi_ipados","wifi_windows","wifi_android","wifi_linux","adminUserManagement_macos","adminUserManagement_windows","adminUserPasswordRotation_macos","adminUserPasswordRotation_windows","deviceNaming_macos","deviceNaming_windows","deviceNaming_linux","googleChrome_macos","googleChrome_windows","firewall_macos","firewall_windows","usbBlocking_macos","usbBlocking_windows","usbBlocking_linux","usbBlocking_android","entraSSO_macos","oktaSSO_macos","primoSSO_macos","customFile_macos","customFile_ios","customFile_ipados","customFile_windows","customFile_android","customFile_linux","passwordPolicy_macos","passwordPolicy_windows","passwordPolicy_ios","passwordPolicy_ipados","passwordPolicy_android","sentinelOne_macos","sentinelOne_windows","sentinelOne_windows_arm64","sentinelOne_linux_deb","sentinelOne_linux_deb_arm64","sentinelOne_linux_rpm","sentinelOne_linux_rpm_arm64","diskEncryption_all","osUpdate_macos","osUpdate_windows","osUpdate_ios","osUpdate_ipados","rustdesk_macos","rustdesk_windows","disableProfilesPane_macos","screenCapture_macos","disableAirdrop_macos","airPrint_macos","webClip_macos","webClip_ios","webClip_ipados"]},"name":{"description":"New display name. Omit to leave it unchanged.","type":"string","minLength":1},"enabled":{"description":"New enabled state. Omit to leave it unchanged.","type":"boolean"},"configurationPayload":{"description":"Full replacement config payload for the control, in clear values. Omit the field to leave the current config unchanged; send null to clear it. A partial payload is not merged — when present, send the whole config, secret fields included (GET returns them in clear, so they can be sent back unchanged).","anyOf":[{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},{"type":"null"}]},"targetMethod":{"description":"How the control is targeted. Omit to leave targeting unchanged. \"All\" ignores the group fields below.","type":"string","enum":["All","DeviceGroup"]},"includedDeviceGroupIds":{"description":"Device group IDs to include. Used only when targetMethod is \"DeviceGroup\".","type":"array","items":{"type":"string"}},"excludedDeviceGroupIds":{"description":"Device group IDs to exclude. Used only when targetMethod is \"DeviceGroup\".","type":"array","items":{"type":"string"}}},"required":["type"]},"UpdateMdmControl_Output":{"type":"object","properties":{"success":{"type":"boolean","description":"Whether the MDM control was updated."}},"required":["success"],"additionalProperties":false},"UpdateMdmControlTagsBody":{"type":"object","properties":{"tags":{"description":"Full replacement set of tags for the control. Any existing tag not in this list is removed.","type":"array","items":{"type":"string"}}},"required":["tags"]},"UpdateMdmControlTags_Output":{"type":"object","properties":{"success":{"type":"boolean","description":"Whether the MDM control tags were updated."}},"required":["success"],"additionalProperties":false},"DeleteMdmControl_Output":{"type":"object","properties":{"success":{"type":"boolean","description":"Whether the MDM control was deleted."}},"required":["success"],"additionalProperties":false},"GetDeviceGroups_Output":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"description":"Device group ID","type":"string"},"name":{"description":"Device group name","type":"string"}},"required":["id","name"],"additionalProperties":false}},"pagination":{"type":"object","properties":{"totalElements":{"type":"integer","minimum":0,"maximum":9007199254740991},"totalPages":{"type":"integer","minimum":0,"maximum":9007199254740991},"page":{"type":"integer","minimum":1,"maximum":9007199254740991},"perPage":{"type":"integer","minimum":1,"maximum":100}},"required":["totalElements","totalPages","page","perPage"],"additionalProperties":false}},"required":["data","pagination"],"additionalProperties":false},"GetDeviceGroupRelations_Output":{"type":"object","properties":{"softwares":{"type":"array","description":"Softwares that target this device group. The group cannot be deleted while this is non-empty.","items":{"type":"object","properties":{"id":{"description":"ID of the resource targeting this device group","type":"string"},"name":{"description":"Human-readable name of the resource","type":"string"}},"required":["id","name"],"additionalProperties":false}},"mdmControls":{"type":"array","description":"MDM controls that target this device group. The group cannot be deleted while this is non-empty.","items":{"type":"object","properties":{"id":{"description":"ID of the resource targeting this device group","type":"string"},"name":{"description":"Human-readable name of the resource","type":"string"}},"required":["id","name"],"additionalProperties":false}}},"required":["softwares","mdmControls"],"additionalProperties":false},"GetDeviceGroupFiltersOptions_Output":{"type":"object","properties":{"filterOptions":{"type":"array","description":"Every criterion that may target a device group. Build the target by placing, at each option's `key`, a clause { operationType, values }; add top-level `matchAny: true` for OR across clauses.","items":{"type":"object","properties":{"key":{"description":"For a native criterion, the path inside the device-group target where the clause is written (e.g. \"owner.teamIds\", \"health.batteryHealth\"). For a custom field, the customFieldId.","type":"string"},"kind":{"description":"Whether this option targets a native device attribute or a custom field.","type":"string","enum":["native","custom_field"]},"valueType":{"description":"How many values the clause accepts: multiple, exactly one, or a boolean flag.","type":"string","enum":["multi_select","single_select","flag"]},"operationTypes":{"description":"The values allowed for the clause's `operationType` field. A clause is written as { operationType: <one of these>, values: [...] } at this option's `key`.","type":"array","items":{"type":"string","enum":["INCLUDE","EXCLUDE"]}},"supportsEmpty":{"description":"Whether this criterion can match the \"unset\" case.","type":"boolean"},"description":{"description":"Human-readable description of what this criterion filters on.","type":"string"},"values":{"description":"The allowed values for this option, with live company data inline.","type":"array","items":{"description":"One allowed value of a Filter option.","type":"object","properties":{"value":{"description":"The raw value to write into the target clause.","type":"string"},"label":{"description":"Human-readable label. For static enum values this equals `value`.","type":"string"}},"required":["value","label"],"additionalProperties":false}}},"required":["key","kind","valueType","operationTypes","supportsEmpty","description","values"],"additionalProperties":false}},"supportsMatchAny":{"type":"boolean","description":"Whether the target supports the top-level matchAny (OR) toggle."}},"required":["filterOptions","supportsMatchAny"],"additionalProperties":false},"CreateDeviceGroupInput":{"type":"object","properties":{"name":{"description":"Device group name","type":"string","minLength":1},"target":{"description":"Device-group target filter. An object keyed by criterion `key` (from the /device-groups/filters-options catalog); each value is a clause { operationType: \"INCLUDE\" | \"EXCLUDE\", values: string[] } — never a bare array. Add top-level `matchAny: true` for OR across clauses. Example: { \"platform\": { \"operationType\": \"INCLUDE\", \"values\": [\"MACOS\"] } }.","type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"required":["name","target"]},"CreateDeviceGroup_Output":{"type":"object","properties":{"id":{"type":"string","description":"Device group ID"},"name":{"type":"string","description":"Device group name"},"target":{"type":"object","description":"Device-group target filter. An object keyed by criterion `key` (from the /device-groups/filters-options catalog); each value is a clause { operationType: \"INCLUDE\" | \"EXCLUDE\", values: string[] } — never a bare array. Add top-level `matchAny: true` for OR across clauses. Example: { \"platform\": { \"operationType\": \"INCLUDE\", \"values\": [\"MACOS\"] } }.","propertyNames":{"type":"string"},"additionalProperties":{}}},"required":["id","name","target"],"additionalProperties":false},"UpdateDeviceGroupInput":{"type":"object","properties":{"name":{"description":"Device group name","type":"string","minLength":1},"target":{"description":"Device-group target filter. An object keyed by criterion `key` (from the /device-groups/filters-options catalog); each value is a clause { operationType: \"INCLUDE\" | \"EXCLUDE\", values: string[] } — never a bare array. Add top-level `matchAny: true` for OR across clauses. Example: { \"platform\": { \"operationType\": \"INCLUDE\", \"values\": [\"MACOS\"] } }.","type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"required":["name","target"]},"UpdateDeviceGroup_Output":{"type":"object","properties":{"id":{"type":"string","description":"Device group ID"},"name":{"type":"string","description":"Device group name"},"target":{"type":"object","description":"Device-group target filter. An object keyed by criterion `key` (from the /device-groups/filters-options catalog); each value is a clause { operationType: \"INCLUDE\" | \"EXCLUDE\", values: string[] } — never a bare array. Add top-level `matchAny: true` for OR across clauses. Example: { \"platform\": { \"operationType\": \"INCLUDE\", \"values\": [\"MACOS\"] } }.","propertyNames":{"type":"string"},"additionalProperties":{}}},"required":["id","name","target"],"additionalProperties":false},"DeleteDeviceGroup_Output":{"type":"object","properties":{"success":{"type":"boolean","description":"Whether the device group was deleted."}},"required":["success"],"additionalProperties":false},"ValidateDeviceGroupTargetInput":{"type":"object","properties":{"target":{"description":"Device group target to validate. An object keyed by criterion `key` (from the /device-groups/filters-options catalog); each value is a clause { operationType: \"INCLUDE\" | \"EXCLUDE\", values: string[] }. Add top-level `matchAny: true` for OR across clauses.","type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"required":["target"]},"ValidateDeviceGroupTarget_Output":{"type":"object","properties":{"valid":{"type":"boolean","description":"Whether the target can be used to create or update a device group."},"errors":{"type":"array","description":"Why the target is invalid — malformed clauses, or criteria that are not device-group-targetable.","items":{"type":"string"}},"matchedCount":{"type":"integer","description":"How many devices the target currently matches. 0 when the target is invalid.","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["valid","errors","matchedCount"],"additionalProperties":false},"GetDeviceGroup_Output":{"type":"object","properties":{"id":{"type":"string","description":"Device group ID"},"name":{"type":"string","description":"Device group name"},"target":{"type":"object","description":"The device-group target filter — the same shape accepted by create/update. Read this, change what you need, and send it back on PUT to preserve targeting when renaming.","propertyNames":{"type":"string"},"additionalProperties":{}},"deviceIds":{"type":"array","description":"IDs of devices currently resolved by this device group target","items":{"type":"string"}}},"required":["id","name","target","deviceIds"],"additionalProperties":false},"GetEmployees_Output":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"firstName":{"type":"string"},"lastName":{"type":"string"},"email":{"type":"string"},"teams":{"description":"Teams the employee belongs to. Empty only when no team is assigned — group by `name` to count per team.","type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false}},"jobs":{"description":"Job titles held by the employee. Empty only when no job title is assigned.","type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false}},"groups":{"description":"Employee groups the employee belongs to.","type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false}},"workLocation":{"description":"Office the employee is attached to. Null for a remote employee.","anyOf":[{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]},"legalEntity":{"description":"Legal entity employing them.","anyOf":[{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]},"managerId":{"description":"Id of the manager employee.","anyOf":[{"type":"string"},{"type":"null"}]},"startDate":{"description":"Employment start date (ISO 8601).","anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"terminationDate":{"description":"Employment end date (ISO 8601).","anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"onboardingStatus":{"description":"Null when the employee has no onboarding.","anyOf":[{"type":"string","enum":["PENDING","SCHEDULED","IN_PROGRESS","CLOSED","CANCELED"]},{"type":"null"}]},"offboardingStatus":{"description":"Null when the employee has no offboarding.","anyOf":[{"type":"string","enum":["PENDING","SCHEDULED","IN_PROGRESS","CLOSED","CANCELED"]},{"type":"null"}]},"lastEnrollmentRequestSentAt":{"description":"When the last MDM enrollment request was emailed to the employee (ISO 8601). Null if none ever was.","anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"enrollmentReminderEnabled":{"description":"Whether the built-in enrollment reminder job is allowed to re-send to this employee.","type":"boolean"},"enrollmentReminderStatus":{"description":"Where the employee stands in the built-in enrollment reminder cycle. See the tool description for what each value means.","type":"string","enum":["NEVER_SENT","REMINDER_CYCLE_ACTIVE","REMINDER_CYCLE_STALLED","REMINDERS_DISABLED"]},"deviceIds":{"description":"Ids of the devices assigned to the employee.","type":"array","items":{"type":"string"}},"accessoryIds":{"description":"Ids of the accessories assigned to the employee.","type":"array","items":{"type":"string"}},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","firstName","lastName","email","teams","jobs","groups","onboardingStatus","offboardingStatus","lastEnrollmentRequestSentAt","enrollmentReminderEnabled","enrollmentReminderStatus","deviceIds","accessoryIds","createdAt","updatedAt"],"additionalProperties":false}},"pagination":{"type":"object","properties":{"totalElements":{"type":"integer","minimum":0,"maximum":9007199254740991},"totalPages":{"type":"integer","minimum":0,"maximum":9007199254740991},"page":{"type":"integer","minimum":1,"maximum":9007199254740991},"perPage":{"type":"integer","minimum":1,"maximum":100}},"required":["totalElements","totalPages","page","perPage"],"additionalProperties":false}},"required":["data","pagination"],"additionalProperties":false},"CreateEmployeeBody":{"type":"object","properties":{"firstName":{"description":"First name of the employee","type":"string","minLength":1},"lastName":{"description":"Last name of the employee","type":"string","minLength":1},"email":{"description":"Work email address of the employee","type":"string","format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},"startDate":{"description":"Employment start date (ISO 8601)","anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"managerId":{"description":"ID of the manager employee","anyOf":[{"type":"string"},{"type":"null"}]},"teams":{"description":"List of team names","type":"array","items":{"type":"string"}},"jobs":{"description":"List of job titles","type":"array","items":{"type":"string"}},"groups":{"description":"List of group names","type":"array","items":{"type":"string"}},"workLocation":{"description":"Work location name","anyOf":[{"type":"string"},{"type":"null"}]},"legalEntity":{"description":"Legal entity name","anyOf":[{"type":"string"},{"type":"null"}]}},"required":["firstName","lastName","email"]},"GetEmployee_Output":{"type":"object","properties":{"id":{"type":"string"},"firstName":{"type":"string"},"lastName":{"type":"string"},"email":{"type":"string"},"teams":{"type":"array","description":"Teams the employee belongs to. Empty only when no team is assigned — group by `name` to count per team.","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false}},"jobs":{"type":"array","description":"Job titles held by the employee. Empty only when no job title is assigned.","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false}},"groups":{"type":"array","description":"Employee groups the employee belongs to.","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false}},"workLocation":{"description":"Office the employee is attached to. Null for a remote employee.","anyOf":[{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]},"legalEntity":{"description":"Legal entity employing them.","anyOf":[{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]},"managerId":{"description":"Id of the manager employee.","anyOf":[{"type":"string"},{"type":"null"}]},"startDate":{"description":"Employment start date (ISO 8601).","anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"terminationDate":{"description":"Employment end date (ISO 8601).","anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"onboardingStatus":{"description":"Null when the employee has no onboarding.","anyOf":[{"type":"string","enum":["PENDING","SCHEDULED","IN_PROGRESS","CLOSED","CANCELED"]},{"type":"null"}]},"offboardingStatus":{"description":"Null when the employee has no offboarding.","anyOf":[{"type":"string","enum":["PENDING","SCHEDULED","IN_PROGRESS","CLOSED","CANCELED"]},{"type":"null"}]},"lastEnrollmentRequestSentAt":{"description":"When the last MDM enrollment request was emailed to the employee (ISO 8601). Null if none ever was.","anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"enrollmentReminderEnabled":{"type":"boolean","description":"Whether the built-in enrollment reminder job is allowed to re-send to this employee."},"enrollmentReminderStatus":{"type":"string","description":"Where the employee stands in the built-in enrollment reminder cycle. See the tool description for what each value means.","enum":["NEVER_SENT","REMINDER_CYCLE_ACTIVE","REMINDER_CYCLE_STALLED","REMINDERS_DISABLED"]},"deviceIds":{"type":"array","description":"Ids of the devices assigned to the employee.","items":{"type":"string"}},"accessoryIds":{"type":"array","description":"Ids of the accessories assigned to the employee.","items":{"type":"string"}},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"personalEmail":{"description":"Personal email address of the employee","anyOf":[{"type":"string"},{"type":"null"}]},"address":{"description":"Personal (home) address of the employee, when known. Use it as the HOME shipping address when ordering equipment for a remote employee. Null when the employee record has no address — ask for one instead of composing it.","anyOf":[{"type":"object","properties":{"street":{"type":"string"},"complement":{"anyOf":[{"type":"string"},{"type":"null"}]},"postalCode":{"type":"string"},"city":{"type":"string"},"countryCode":{"description":"ISO 3166-1 alpha-2 country code","anyOf":[{"type":"string"},{"type":"null"}]},"phone":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["street","postalCode","city"],"additionalProperties":false},{"type":"null"}]},"employmentType":{"type":"string","description":"Employment type of the employee","enum":["INTERNAL","CONTRACTOR"]},"isRemote":{"type":"boolean","description":"Whether the employee works remotely. Derived from the absence of a work location: an employee with no assigned work location has no office to deliver equipment to and is treated as remote."}},"required":["id","firstName","lastName","email","teams","jobs","groups","onboardingStatus","offboardingStatus","lastEnrollmentRequestSentAt","enrollmentReminderEnabled","enrollmentReminderStatus","deviceIds","accessoryIds","createdAt","updatedAt","employmentType","isRemote"],"additionalProperties":false},"UpdateEmployeeBody":{"type":"object","properties":{"firstName":{"description":"First name of the employee","type":"string","minLength":1},"lastName":{"description":"Last name of the employee","type":"string","minLength":1},"email":{"description":"Work email address of the employee","type":"string","format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},"personalEmail":{"description":"Personal email address of the employee","anyOf":[{"type":"string","format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},{"type":"null"}]},"phone":{"description":"Phone number of the employee","anyOf":[{"type":"string"},{"type":"null"}]},"gender":{"description":"Gender of the employee","anyOf":[{"type":"string","enum":["MALE","FEMALE","OTHER","PREFER_NOT_TO_DISCLOSE"]},{"type":"null"}]},"picture":{"description":"URL of the employee profile picture","anyOf":[{"type":"string"},{"type":"null"}]},"managerId":{"description":"ID of the manager employee","anyOf":[{"type":"string"},{"type":"null"}]},"employmentType":{"description":"Employment type of the employee","type":"string","enum":["INTERNAL","CONTRACTOR"]},"job":{"description":"Job title. Created if it does not exist yet.","anyOf":[{"type":"object","properties":{"id":{"description":"ID of an existing reference. Omit or set null to create/match by name.","anyOf":[{"type":"string"},{"type":"null"}]},"name":{"description":"Display name of the reference.","type":"string","minLength":1}},"required":["name"]},{"type":"null"}]},"teams":{"description":"Teams the employee belongs to. Replaces the current set. Teams are created if they do not exist yet.","type":"array","items":{"type":"object","properties":{"id":{"anyOf":[{"type":"string"},{"type":"null"}]},"name":{"type":"string","minLength":1}},"required":["id","name"]}},"workLocation":{"description":"Work location. Created if it does not exist yet.","anyOf":[{"type":"object","properties":{"id":{"description":"ID of an existing reference. Omit or set null to create/match by name.","anyOf":[{"type":"string"},{"type":"null"}]},"name":{"description":"Display name of the reference.","type":"string","minLength":1}},"required":["name"]},{"type":"null"}]},"legalEntity":{"description":"Legal entity. Created if it does not exist yet.","anyOf":[{"type":"object","properties":{"id":{"description":"ID of an existing reference. Omit or set null to create/match by name.","anyOf":[{"type":"string"},{"type":"null"}]},"name":{"description":"Display name of the reference.","type":"string","minLength":1}},"required":["name"]},{"type":"null"}]},"address":{"description":"Personal (home) address of the employee. Replaces the whole address; null removes it.","anyOf":[{"type":"object","properties":{"street":{"type":"string","minLength":1},"complement":{"anyOf":[{"type":"string"},{"type":"null"}]},"postalCode":{"type":"string","minLength":1},"city":{"type":"string","minLength":1},"countryCode":{"description":"ISO 3166-1 alpha-2 country code","type":"string","minLength":2,"maxLength":2},"phone":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["street","postalCode","city","countryCode"]},{"type":"null"}]},"startDate":{"description":"First day of the employee (YYYY-MM-DD); null clears it.","anyOf":[{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},{"type":"null"}]},"terminationDate":{"description":"Last day of the employee (YYYY-MM-DD). When an offboarding is open, its termination date follows. Null clears it, refused while an offboarding is open.","anyOf":[{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},{"type":"null"}]}}},"GetEmployeeCustomFields_Output":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"field":{"type":"object","properties":{"id":{"description":"CustomField id (MongoDB ObjectId string).","type":"string"},"label":{"type":"string"},"fieldType":{"description":"Type of data this field holds.","type":"string","enum":["SELECT","MULTI_SELECT","CHECKBOX","TEXT","DATE","NUMBER","URL","IMAGE"]},"applyTo":{"type":"array","items":{"type":"string","enum":["DEVICE","ACCESSORY","EMPLOYEE","ORDER"]}},"options":{"description":"Option catalog. Non-empty only for SELECT / MULTI_SELECT fields. Use option `id` when writing values.","type":"array","items":{"type":"object","properties":{"id":{"description":"Stable UUID of the option. Use this id for SELECT / MULTI_SELECT value writes.","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"value":{"description":"Display label of the option (mutable — ids are the stable identity).","type":"string"}},"required":["id","value"],"additionalProperties":false}}},"required":["id","label","fieldType","applyTo","options"],"additionalProperties":false},"value":{"description":"Current stored value for this field on this employee, or null when unset. For SELECT / MULTI_SELECT the value is the option id (or array of ids). For CHECKBOX it is a boolean. For DATE it is an ISO date string.","anyOf":[{"type":"boolean"},{"type":"number"},{"type":"string"},{"type":"array","items":{"type":"string"}},{"type":"null"}]}},"required":["field","value"],"additionalProperties":false}}},"required":["items"],"additionalProperties":false},"HideEmployee_Output":{"type":"object","properties":{"success":{"type":"boolean","const":true}},"required":["success"],"additionalProperties":false},"SetEmployeeCustomFieldValueBody":{"type":"object","properties":{"value":{"description":"Value to set. Must conform to the field type. Pass null to clear an existing value. For SELECT supply the option id (string). For MULTI_SELECT supply an array of option ids.","anyOf":[{"type":"boolean"},{"type":"number"},{"type":"string"},{"type":"array","items":{"type":"string"}},{"type":"null"}]}},"required":["value"]},"EmployeeCustomFieldItem_Output":{"type":"object","properties":{"field":{"type":"object","properties":{"id":{"description":"CustomField id (MongoDB ObjectId string).","type":"string"},"label":{"type":"string"},"fieldType":{"description":"Type of data this field holds.","type":"string","enum":["SELECT","MULTI_SELECT","CHECKBOX","TEXT","DATE","NUMBER","URL","IMAGE"]},"applyTo":{"type":"array","items":{"type":"string","enum":["DEVICE","ACCESSORY","EMPLOYEE","ORDER"]}},"options":{"description":"Option catalog. Non-empty only for SELECT / MULTI_SELECT fields. Use option `id` when writing values.","type":"array","items":{"type":"object","properties":{"id":{"description":"Stable UUID of the option. Use this id for SELECT / MULTI_SELECT value writes.","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"value":{"description":"Display label of the option (mutable — ids are the stable identity).","type":"string"}},"required":["id","value"],"additionalProperties":false}}},"required":["id","label","fieldType","applyTo","options"],"additionalProperties":false},"value":{"description":"Current stored value for this field on this employee, or null when unset. For SELECT / MULTI_SELECT the value is the option id (or array of ids). For CHECKBOX it is a boolean. For DATE it is an ISO date string.","anyOf":[{"type":"boolean"},{"type":"number"},{"type":"string"},{"type":"array","items":{"type":"string"}},{"type":"null"}]}},"required":["field","value"],"additionalProperties":false},"SendEnrollmentRequest_Output":{"type":"object","properties":{"success":{"type":"boolean","const":true}},"required":["success"],"additionalProperties":false},"GetEquipmentPolicyResponseDto_Output":{"type":"object","properties":{"policy":{"description":"The company equipment policy, or null when no policy has been created yet.","anyOf":[{"type":"object","properties":{"id":{"type":"string"},"status":{"description":"Publication state. \"unpublished\": never published (or hidden). \"pending-changes\": the draft has edits not yet published. \"published\": the draft matches the published text.","type":"string","enum":["unpublished","pending-changes","published"]},"draft":{"description":"The editable draft. This is the text updateEquipmentPolicy writes.","type":"object","properties":{"content":{"description":"The Markdown body of the equipment policy.","type":"string"}},"required":["content"],"additionalProperties":false},"published":{"description":"The published text the AI agent sees at runtime, or null if never published. Diff it against the draft to surface pending edits.","anyOf":[{"type":"object","properties":{"content":{"description":"The Markdown body of the equipment policy.","type":"string"}},"required":["content"],"additionalProperties":false},{"type":"null"}]}},"required":["id","status","draft","published"],"additionalProperties":false},{"type":"null"}]}},"required":["policy"],"additionalProperties":false},"GetEquipmentPolicyResultResponseDto_Output":{"type":"object","properties":{"result":{"type":"object","description":"The computed equipment policy result across all set-up countries.","properties":{"policyId":{"description":"The equipment policy this result was computed from. Empty when never set up.","type":"string"},"products":{"description":"Recommended products keyed by ISO country code. A country is present only once its compute finished.","type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"object","properties":{"devices":{"description":"Recommended device products for this country.","type":"array","items":{"type":"object","properties":{"productId":{"description":"The catalog product ID recommended by the policy for this country.","type":"string"}},"required":["productId"],"additionalProperties":false}},"accessories":{"description":"Recommended accessory products for this country.","type":"array","items":{"type":"object","properties":{"productId":{"description":"The catalog product ID recommended by the policy for this country.","type":"string"}},"required":["productId"],"additionalProperties":false}}},"required":["devices","accessories"],"additionalProperties":false}},"statuses":{"description":"Per-country compute state keyed by ISO country code. \"computing\": still running. \"ready\": products available. \"failed\": compute errored.","type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","enum":["computing","ready","failed"]}},"updatedAt":{"description":"ISO timestamp of the last result write.","type":"string"},"isSetup":{"description":"Whether an equipment policy has actually been set up. False means never configured (empty result).","type":"boolean"}},"required":["policyId","products","statuses","updatedAt","isSetup"],"additionalProperties":false}},"required":["result"],"additionalProperties":false},"GetPurchasingPolicyResponseDto_Output":{"type":"object","properties":{"policy":{"description":"The company purchasing policy, or null when no policy has been created yet.","anyOf":[{"type":"object","properties":{"id":{"type":"string"},"status":{"description":"Publication state. \"unpublished\": never published (or hidden). \"pending-changes\": the draft has edits not yet published. \"published\": the draft matches the published text.","type":"string","enum":["unpublished","pending-changes","published"]},"draft":{"description":"The editable draft. This is the text updatePurchasingPolicy writes.","type":"object","properties":{"content":{"description":"The Markdown body of the purchasing policy.","type":"string"}},"required":["content"],"additionalProperties":false},"published":{"description":"The published text the AI agent sees at runtime, or null if never published. Diff it against the draft to surface pending edits.","anyOf":[{"type":"object","properties":{"content":{"description":"The Markdown body of the purchasing policy.","type":"string"}},"required":["content"],"additionalProperties":false},{"type":"null"}]}},"required":["id","status","draft","published"],"additionalProperties":false},{"type":"null"}]}},"required":["policy"],"additionalProperties":false},"GetAccessories_Output":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"ownerId":{"description":"Employee ID currently assigned to this accessory","anyOf":[{"type":"string"},{"type":"null"}]},"name":{"type":"string"},"type":{"type":"string","enum":["MONITOR","KEYBOARD","MOUSE","MOUSEPAD","WEBCAM","HEADSET","SPEAKER","CABLE_ADAPTER","HUB","CHARGER","STORAGE_DEVICE","LAPTOP_CASE","ERGONOMIC","SHIPPING_MATERIAL","FIDO_KEY","ACCESS_CARD","NETWORK_DEVICE","FIREWALL","ROUTER","SWITCH","OTHER"]},"brand":{"anyOf":[{"type":"string"},{"type":"null"}]},"model":{"anyOf":[{"type":"string"},{"type":"null"}]},"serialNumber":{"anyOf":[{"type":"string"},{"type":"null"}]},"tags":{"type":"array","items":{"type":"string"}},"description":{"description":"Free-form accessory description","anyOf":[{"type":"string"},{"type":"null"}]},"condition":{"description":"Current accessory condition. Null when condition is not specified.","anyOf":[{"type":"string","enum":["NEW","GOOD","DAMAGED","UNUSABLE"]},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","name","type","tags","createdAt","updatedAt"],"additionalProperties":false}},"pagination":{"type":"object","properties":{"totalElements":{"type":"integer","minimum":0,"maximum":9007199254740991},"totalPages":{"type":"integer","minimum":0,"maximum":9007199254740991},"page":{"type":"integer","minimum":1,"maximum":9007199254740991},"perPage":{"type":"integer","minimum":1,"maximum":100}},"required":["totalElements","totalPages","page","perPage"],"additionalProperties":false}},"required":["data","pagination"],"additionalProperties":false},"GetAccessory_Output":{"type":"object","properties":{"id":{"type":"string"},"ownerId":{"description":"Employee ID currently assigned to this accessory","anyOf":[{"type":"string"},{"type":"null"}]},"name":{"type":"string"},"type":{"type":"string","enum":["MONITOR","KEYBOARD","MOUSE","MOUSEPAD","WEBCAM","HEADSET","SPEAKER","CABLE_ADAPTER","HUB","CHARGER","STORAGE_DEVICE","LAPTOP_CASE","ERGONOMIC","SHIPPING_MATERIAL","FIDO_KEY","ACCESS_CARD","NETWORK_DEVICE","FIREWALL","ROUTER","SWITCH","OTHER"]},"brand":{"anyOf":[{"type":"string"},{"type":"null"}]},"model":{"anyOf":[{"type":"string"},{"type":"null"}]},"serialNumber":{"anyOf":[{"type":"string"},{"type":"null"}]},"tags":{"type":"array","items":{"type":"string"}},"description":{"description":"Free-form accessory description","anyOf":[{"type":"string"},{"type":"null"}]},"condition":{"description":"Current accessory condition. Null when condition is not specified.","anyOf":[{"type":"string","enum":["NEW","GOOD","DAMAGED","UNUSABLE"]},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","name","type","tags","createdAt","updatedAt"],"additionalProperties":false},"CreateAccessoryBody":{"type":"object","properties":{"ownerId":{"description":"Employee ID to assign the accessory to","anyOf":[{"type":"string","pattern":"^[a-f\\d]{24}$"},{"type":"null"}]},"name":{"type":"string","minLength":1},"type":{"type":"string","enum":["MONITOR","KEYBOARD","MOUSE","MOUSEPAD","WEBCAM","HEADSET","SPEAKER","CABLE_ADAPTER","HUB","CHARGER","STORAGE_DEVICE","LAPTOP_CASE","ERGONOMIC","SHIPPING_MATERIAL","FIDO_KEY","ACCESS_CARD","NETWORK_DEVICE","FIREWALL","ROUTER","SWITCH","OTHER"]},"brand":{"anyOf":[{"type":"string"},{"type":"null"}]},"model":{"anyOf":[{"type":"string"},{"type":"null"}]},"serialNumber":{"anyOf":[{"type":"string"},{"type":"null"}]},"tags":{"type":"array","items":{"type":"string"}},"description":{"anyOf":[{"type":"string"},{"type":"null"}]},"condition":{"description":"Accessory condition. Set to null to clear the current condition.","anyOf":[{"type":"string","enum":["NEW","GOOD","DAMAGED","UNUSABLE"]},{"type":"null"}]}},"required":["name","type"]},"UpdateAccessoryBody":{"type":"object","properties":{"ownerId":{"anyOf":[{"type":"string","pattern":"^[a-f\\d]{24}$"},{"type":"null"}]},"name":{"type":"string","minLength":1},"type":{"type":"string","enum":["MONITOR","KEYBOARD","MOUSE","MOUSEPAD","WEBCAM","HEADSET","SPEAKER","CABLE_ADAPTER","HUB","CHARGER","STORAGE_DEVICE","LAPTOP_CASE","ERGONOMIC","SHIPPING_MATERIAL","FIDO_KEY","ACCESS_CARD","NETWORK_DEVICE","FIREWALL","ROUTER","SWITCH","OTHER"]},"brand":{"anyOf":[{"type":"string"},{"type":"null"}]},"model":{"anyOf":[{"type":"string"},{"type":"null"}]},"serialNumber":{"anyOf":[{"type":"string"},{"type":"null"}]},"tags":{"type":"array","items":{"type":"string"}},"description":{"anyOf":[{"type":"string"},{"type":"null"}]},"condition":{"anyOf":[{"type":"string","enum":["NEW","GOOD","DAMAGED","UNUSABLE"]},{"type":"null"}]}},"required":["ownerId","name","type","brand","model","serialNumber","tags","description","condition"]},"GetAccessoryCustomFields_Output":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"field":{"type":"object","properties":{"id":{"description":"CustomField id (MongoDB ObjectId string).","type":"string"},"label":{"type":"string"},"fieldType":{"description":"Type of data this field holds.","type":"string","enum":["SELECT","MULTI_SELECT","CHECKBOX","TEXT","DATE","NUMBER","URL","IMAGE"]},"applyTo":{"type":"array","items":{"type":"string","enum":["DEVICE","ACCESSORY","EMPLOYEE","ORDER"]}},"options":{"description":"Option catalog. Non-empty only for SELECT / MULTI_SELECT fields. Use option `id` when writing values.","type":"array","items":{"type":"object","properties":{"id":{"description":"Stable UUID of the option. Use this id for SELECT / MULTI_SELECT value writes.","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"value":{"description":"Display label of the option (mutable — ids are the stable identity).","type":"string"}},"required":["id","value"],"additionalProperties":false}}},"required":["id","label","fieldType","applyTo","options"],"additionalProperties":false},"value":{"description":"Current stored value for this field on this accessory, or null when unset. For SELECT / MULTI_SELECT the value is the option id (or array of ids). For CHECKBOX it is a boolean. For DATE it is an ISO date string. For IMAGE it is a signed URL of the picture, valid 12 hours from the read.","anyOf":[{"type":"boolean"},{"type":"number"},{"type":"string"},{"type":"array","items":{"type":"string"}},{"type":"null"}]}},"required":["field","value"],"additionalProperties":false}}},"required":["items"],"additionalProperties":false},"SetAccessoryCustomFieldValueBody":{"type":"object","properties":{"value":{"description":"Value to set. Must conform to the field type. Pass null to clear an existing value. For SELECT supply the option id (string). For MULTI_SELECT supply an array of option ids. An IMAGE field only accepts null here: its picture is uploaded from the cockpit, any other value is refused with 400.","anyOf":[{"type":"boolean"},{"type":"number"},{"type":"string"},{"type":"array","items":{"type":"string"}},{"type":"null"}]}},"required":["value"]},"AccessoryCustomFieldItem_Output":{"type":"object","properties":{"field":{"type":"object","properties":{"id":{"description":"CustomField id (MongoDB ObjectId string).","type":"string"},"label":{"type":"string"},"fieldType":{"description":"Type of data this field holds.","type":"string","enum":["SELECT","MULTI_SELECT","CHECKBOX","TEXT","DATE","NUMBER","URL","IMAGE"]},"applyTo":{"type":"array","items":{"type":"string","enum":["DEVICE","ACCESSORY","EMPLOYEE","ORDER"]}},"options":{"description":"Option catalog. Non-empty only for SELECT / MULTI_SELECT fields. Use option `id` when writing values.","type":"array","items":{"type":"object","properties":{"id":{"description":"Stable UUID of the option. Use this id for SELECT / MULTI_SELECT value writes.","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"value":{"description":"Display label of the option (mutable — ids are the stable identity).","type":"string"}},"required":["id","value"],"additionalProperties":false}}},"required":["id","label","fieldType","applyTo","options"],"additionalProperties":false},"value":{"description":"Current stored value for this field on this accessory, or null when unset. For SELECT / MULTI_SELECT the value is the option id (or array of ids). For CHECKBOX it is a boolean. For DATE it is an ISO date string. For IMAGE it is a signed URL of the picture, valid 12 hours from the read.","anyOf":[{"type":"boolean"},{"type":"number"},{"type":"string"},{"type":"array","items":{"type":"string"}},{"type":"null"}]}},"required":["field","value"],"additionalProperties":false},"AssignAccessoryBody":{"type":"object","properties":{"ownerId":{"description":"Employee ID to assign the accessory to. Pass null to unassign.","anyOf":[{"type":"string","pattern":"^[a-f\\d]{24}$"},{"type":"null"}]}},"required":["ownerId"]},"AccessoryActionSuccess_Output":{"type":"object","properties":{"success":{"type":"boolean","const":true}},"required":["success"],"additionalProperties":false},"GetComplianceAlerts_Output":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"deviceId":{"type":"string"},"deviceName":{"anyOf":[{"type":"string"},{"type":"null"}]},"devicePlatform":{"anyOf":[{"type":"string","enum":["ANDROID","IOS","IPADOS","MACOS","WINDOWS","LINUX","CHROME_OS","UNKNOWN"]},{"type":"null"}]},"owner":{"description":"Employee the alerting device is assigned to.","anyOf":[{"type":"object","properties":{"id":{"type":"string"},"firstName":{"type":"string"},"lastName":{"type":"string"}},"required":["id","firstName","lastName"],"additionalProperties":false},{"type":"null"}]},"complianceRuleId":{"type":"string"},"ruleType":{"description":"Type of the compliance rule behind the alert.","anyOf":[{"type":"string"},{"type":"null"}]},"mdmControlId":{"anyOf":[{"type":"string"},{"type":"null"}]},"status":{"type":"string","enum":["ACTIVE","NOT_PROTECTED","OFFLINE_7_DAYS","PENDING","PROTECTED","FAILED","NOT_ENCRYPTED","MISSING_RECOVERY_KEY","ENCRYPTED","ACTION_REQUIRED","GRACE_PERIOD","UP_TO_DATE","NOT_UP_TO_DATE","ENFORCED","ERROR","CREATION_PENDING","DEMOTION_PENDING","CREATED","CREATION_FAILED","SUCCESS","UNSUPPORTED","INSTALLED","MDM_ON","MDM_OFF","MDM_ON_IN_ANOTHER_MDM","READY_ZTD","MISSING_AGENT","ONLINE","OFFLINE","ENABLED","DISABLED","MISSING_BYPASS_CODE","MEETS_REQUIREMENTS","BELOW_MINIMUM_VERSION","UNSUPPORTED_OS_EDITION"]},"additionalStatus":{"description":"Narrows `status` when several situations share it. Null when `status` already says everything — a compliant device, or a status only one situation can produce — and on rows computed before this field existed. PROFILE_DELIVERY_PENDING: The MDM profile is queued for delivery; the device has not acknowledged it yet. PROFILE_VERIFYING: The MDM profile was installed and the MDM is verifying it applied. PROFILE_NOT_ON_DEVICE: The MDM has no record of this profile on the device; it was never scoped to it. A resend needs a prior delivery, so refresh the device and re-check the control targeting instead. PROFILE_DELIVERY_FAILED: The device rejected the MDM profile. `detail` carries the MDM error. CONTROL_MISSING_PROFILE: The control has no profile to deploy; this is a Primo configuration issue, not a device issue. POLICY_NOT_EVALUATED: The device has not reported a result for the compliance check yet. POLICY_NOT_ON_DEVICE: The compliance check is not attached to this device in the MDM. POLICY_FAILED: The compliance check attached to the control fails on the device. CONTROL_MISSING_POLICY: The control has no compliance check attached; this is a Primo configuration issue. RECOVERY_OS_STATUS_UNKNOWN: Primo has not computed the recovery OS state of this device yet. RECOVERY_OS_PROTECTION_PENDING: The recovery OS password command was sent and awaits the device. RECOVERY_OS_PROTECTION_FAILED: The device rejected the recovery OS password command. RECOVERY_OS_NOT_PROTECTED: Recovery OS has no password set. RECOVERY_OS_STATUS_UNRECOGNIZED: The device reports a recovery OS state Primo does not know. `detail` carries the raw value. SENTINEL_ONE_AGENT_NOT_INSTALLED: The SentinelOne agent is not installed on the device. SENTINEL_ONE_AGENT_INSTALLED_NOT_REGISTERED: The SentinelOne agent is installed but the device is not registered in the SentinelOne console. MALWAREBYTES_AGENT_NOT_INSTALLED: The Malwarebytes agent is not in the device software inventory and no install ran in the last 24 hours. MALWAREBYTES_INSTALL_IN_PROGRESS: The Malwarebytes install script ran in the last 24 hours; wait for the next inventory sync. `detail` carries the run date. MALWAREBYTES_ENDPOINT_NOT_FOUND: The Malwarebytes agent is installed but the device has no endpoint in the Malwarebytes console; the agent is not registered to the company account. MALWAREBYTES_REGISTRATION_IN_PROGRESS: The Malwarebytes registration script ran in the last hour; wait for the console to sync. `detail` carries the run date. MALWAREBYTES_ENDPOINT_UNPROTECTED: The device exists in the Malwarebytes console but is not protected. `detail` carries the console protection status. MALWAREBYTES_AGENT_NEVER_REPORTED: The Malwarebytes console has no activity date for this device. MALWAREBYTES_AGENT_INACTIVE: The Malwarebytes agent last reported more than 7 days ago. `detail` carries the last activity date. RUSTDESK_INSTALL_NOT_STARTED: No RustDesk installation was recorded for this device yet. RUSTDESK_INSTALL_IN_PROGRESS: The RustDesk installation is in progress. RUSTDESK_INSTALL_FAILED: The RustDesk installation failed on the device. ADMIN_ACCOUNT_CREATION_QUEUED: The managed admin account creation is queued: no creation command has been dispatched to this device yet. ADMIN_ACCOUNT_CREATION_IN_PROGRESS: The managed admin account creation was dispatched and awaits the device. ADMIN_ACCOUNT_PRE_EXISTING: An account with the policy username already exists on the device and was not created by Primo. `detail` carries the username. NO_MANAGED_ADMIN_TO_ROTATE: No local admin account with the policy username exists on the device, nothing to rotate. PASSWORD_ROTATION_UP_TO_DATE: The admin password was rotated within the configured frequency. ADMIN_PASSWORD_UNKNOWN: The admin account was not created by Primo and Primo does not hold its password yet: the next rotation replaces it. `detail` carries the username. NO_SECURE_TOKEN_ADMIN_TO_ROTATE: macOS only: Primo cannot change this password. A reset needs another local admin holding a SecureToken whose password Primo stores, and the device has none. `detail` carries the username. DEVICE_NAME_SUGGESTION_NOT_GENERATED: Primo has not generated the expected name for this device yet. `detail` carries the last failed attempt, if any. DEVICE_NAME_ALREADY_USED: Primo gave up naming this device: the name its rule produces is held by another device of the company. `detail` carries the name and the id of that device — retire it or rename it, then regenerate the name. DEVICE_NAME_SUGGESTION_FAILED: Primo gave up naming this device after repeated invalid AI outputs. `detail` carries the failure type; regenerate the name once the rule is fixed. DEVICE_RENAME_NOT_DISPATCHED: The device name differs from the convention and no rename command is in flight. `detail` carries expected vs actual. DEVICE_RENAME_COMMAND_IN_PROGRESS: A rename command was sent and awaits the device. `detail` carries expected vs actual. DEVICE_OFFLINE_LESS_THAN_7_DAYS: The device has not checked in for less than 7 days. `detail` carries the last check-in. DEVICE_LAST_SEEN_UNKNOWN: The MDM reports no valid last check-in date for this device.","anyOf":[{"type":"string","enum":["MALWAREBYTES_AGENT_NOT_INSTALLED","MALWAREBYTES_INSTALL_IN_PROGRESS","MALWAREBYTES_ENDPOINT_NOT_FOUND","MALWAREBYTES_REGISTRATION_IN_PROGRESS","MALWAREBYTES_ENDPOINT_UNPROTECTED","MALWAREBYTES_AGENT_NEVER_REPORTED","MALWAREBYTES_AGENT_INACTIVE","RECOVERY_OS_STATUS_UNKNOWN","RECOVERY_OS_PROTECTION_PENDING","RECOVERY_OS_PROTECTION_FAILED","RECOVERY_OS_NOT_PROTECTED","RECOVERY_OS_STATUS_UNRECOGNIZED","PROFILE_DELIVERY_PENDING","PROFILE_VERIFYING","PROFILE_NOT_ON_DEVICE","PROFILE_DELIVERY_FAILED","CONTROL_MISSING_PROFILE","POLICY_NOT_EVALUATED","POLICY_NOT_ON_DEVICE","POLICY_FAILED","CONTROL_MISSING_POLICY","ADMIN_ACCOUNT_CREATION_QUEUED","ADMIN_ACCOUNT_CREATION_IN_PROGRESS","ADMIN_ACCOUNT_PRE_EXISTING","NO_MANAGED_ADMIN_TO_ROTATE","PASSWORD_ROTATION_UP_TO_DATE","ADMIN_PASSWORD_UNKNOWN","NO_SECURE_TOKEN_ADMIN_TO_ROTATE","DEVICE_NAME_SUGGESTION_NOT_GENERATED","DEVICE_NAME_ALREADY_USED","DEVICE_NAME_SUGGESTION_FAILED","DEVICE_RENAME_NOT_DISPATCHED","DEVICE_RENAME_COMMAND_IN_PROGRESS","SENTINEL_ONE_AGENT_NOT_INSTALLED","SENTINEL_ONE_AGENT_INSTALLED_NOT_REGISTERED","RUSTDESK_INSTALL_NOT_STARTED","RUSTDESK_INSTALL_IN_PROGRESS","RUSTDESK_INSTALL_FAILED","DEVICE_OFFLINE_LESS_THAN_7_DAYS","DEVICE_LAST_SEEN_UNKNOWN"]},{"type":"null"}]},"detail":{"description":"Raw evidence behind `additionalStatus` when one exists (an MDM error, an upstream protection status, a date, a name). Human readable, not stable.","anyOf":[{"type":"string"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"description":"When the compliance of the device was last checked.","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"statusSince":{"description":"When the device was first observed carrying the current status. Resets on every status change, including between two non-compliant statuses. Null until the device syncs for the first time.","anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]}},"required":["id","deviceId","deviceName","devicePlatform","owner","complianceRuleId","ruleType","mdmControlId","status","additionalStatus","detail","createdAt","updatedAt","statusSince"],"additionalProperties":false}},"pagination":{"type":"object","properties":{"totalElements":{"type":"integer","minimum":0,"maximum":9007199254740991},"totalPages":{"type":"integer","minimum":0,"maximum":9007199254740991},"page":{"type":"integer","minimum":1,"maximum":9007199254740991},"perPage":{"type":"integer","minimum":1,"maximum":100}},"required":["totalElements","totalPages","page","perPage"],"additionalProperties":false}},"required":["data","pagination"],"additionalProperties":false},"SearchComplianceAlertsBody":{"type":"object","properties":{"page":{"default":1,"type":"integer","minimum":1,"maximum":9007199254740991},"perPage":{"default":50,"type":"integer","minimum":1,"maximum":100},"filter":{"description":"One entry per criterion, keyed by the `key` returned by the filter catalog (`GET /compliance/alerts/filters-options`). Every value is a clause { operationType, values } — never a bare value, never an operator like `eq`. Criteria are ANDed. An unknown key is rejected with 400 rather than ignored.","type":"object","properties":{"deviceId":{"type":"object","properties":{"operationType":{"description":"INCLUDE keeps the alerts matching the values, EXCLUDE keeps the alerts that do not.","type":"string","enum":["INCLUDE","EXCLUDE"]},"values":{"description":"Device ids, as returned by getDevices.","minItems":1,"type":"array","items":{"type":"string","pattern":"^[a-f\\d]{24}$"}}},"required":["operationType","values"]},"platform":{"type":"object","properties":{"operationType":{"description":"INCLUDE keeps the alerts matching the values, EXCLUDE keeps the alerts that do not.","type":"string","enum":["INCLUDE","EXCLUDE"]},"values":{"description":"Device platforms.","minItems":1,"type":"array","items":{"type":"string","enum":["ANDROID","IOS","IPADOS","MACOS","WINDOWS","LINUX","CHROME_OS","UNKNOWN"]}}},"required":["operationType","values"]},"ownerId":{"type":"object","properties":{"operationType":{"description":"INCLUDE keeps the alerts matching the values, EXCLUDE keeps the alerts that do not.","type":"string","enum":["INCLUDE","EXCLUDE"]},"values":{"description":"Employee ids the devices are assigned to, as returned by getEmployees.","minItems":1,"type":"array","items":{"type":"string","pattern":"^[a-f\\d]{24}$"}}},"required":["operationType","values"]},"status":{"type":"object","properties":{"operationType":{"description":"INCLUDE keeps the alerts matching the values, EXCLUDE keeps the alerts that do not.","type":"string","enum":["INCLUDE","EXCLUDE"]},"values":{"description":"Non-compliant statuses carried by the alert.","minItems":1,"type":"array","items":{"type":"string","enum":["NOT_ENCRYPTED","MISSING_RECOVERY_KEY","ACTION_REQUIRED","NOT_UP_TO_DATE","FAILED","ERROR","CREATION_FAILED","NOT_PROTECTED","MISSING_AGENT","MDM_OFF","MDM_ON_IN_ANOTHER_MDM","OFFLINE_7_DAYS","MISSING_BYPASS_CODE","BELOW_MINIMUM_VERSION","UNSUPPORTED_OS_EDITION","PENDING","CREATION_PENDING","DEMOTION_PENDING","READY_ZTD","GRACE_PERIOD","OFFLINE"]}}},"required":["operationType","values"]},"type":{"type":"object","properties":{"operationType":{"description":"INCLUDE keeps the alerts matching the values, EXCLUDE keeps the alerts that do not.","type":"string","enum":["INCLUDE","EXCLUDE"]},"values":{"description":"Compliance rule types behind the alert.","minItems":1,"type":"array","items":{"type":"string","enum":["MDM_CONTROL_MALWAREBYTES","MDM_CONTROL_RECOVERY_OS","MDM_CONTROL_ENCRYPTION","MDM_CONTROL_OS_UPDATE","MDM_CONTROL_SOFTWARE_UPDATE","MDM_CONTROL_WIFI","MDM_CONTROL_ADMIN_USER_MANAGEMENT","MDM_CONTROL_ADMIN_USER_PASSWORD_ROTATION","MDM_CONTROL_DEVICE_NAMING","MDM_CONTROL_GOOGLE_CHROME","MDM_CONTROL_FIREWALL","MDM_CONTROL_USB_BLOCKING","MDM_CONTROL_ENTRA_SSO","MDM_CONTROL_OKTA_SSO","MDM_CONTROL_CUSTOM_FILE","MDM_CONTROL_PASSWORD_POLICY","MDM_CONTROL_SENTINEL_ONE","MDM_CONTROL_RUSTDESK","MDM_CONTROL_APP_BLOCKING","MDM_CONTROL_DISABLE_PROFILES_PANE","MDM_CONTROL_DISABLE_AIRDROP","MDM_CONTROL_SCREEN_CAPTURE","MDM_CONTROL_AIR_PRINT","MDM_CONTROL_PRIMO_SSO","MDM_CONTROL_WEB_CLIP","MDM_ENROLLMENT","MDM_ONLINE","MDM_ICLOUD_LOCK_STATUS","PRIMO_REQUIREMENT"]}}},"required":["operationType","values"]},"checkedAt":{"type":"object","properties":{"operationType":{"type":"string","const":"INCLUDE"},"values":{"description":"Exactly one relative bucket of how long ago the device compliance was last checked.","minItems":1,"maxItems":1,"type":"array","items":{"type":"string","enum":["UNDER_24_HOURS","ONE_TO_SEVEN_DAYS","SEVEN_TO_THIRTY_DAYS","THIRTY_TO_NINETY_DAYS","OVER_NINETY_DAYS"]}}},"required":["operationType","values"]}},"additionalProperties":false}}},"GetComplianceAlertDetails_Output":{"type":"object","properties":{"alert":{"type":"object","properties":{"id":{"type":"string"},"deviceId":{"type":"string"},"deviceName":{"anyOf":[{"type":"string"},{"type":"null"}]},"devicePlatform":{"anyOf":[{"type":"string","enum":["ANDROID","IOS","IPADOS","MACOS","WINDOWS","LINUX","CHROME_OS","UNKNOWN"]},{"type":"null"}]},"owner":{"description":"Employee the alerting device is assigned to.","anyOf":[{"type":"object","properties":{"id":{"type":"string"},"firstName":{"type":"string"},"lastName":{"type":"string"}},"required":["id","firstName","lastName"],"additionalProperties":false},{"type":"null"}]},"complianceRuleId":{"type":"string"},"ruleType":{"description":"Type of the compliance rule behind the alert.","anyOf":[{"type":"string"},{"type":"null"}]},"mdmControlId":{"anyOf":[{"type":"string"},{"type":"null"}]},"status":{"type":"string","enum":["ACTIVE","NOT_PROTECTED","OFFLINE_7_DAYS","PENDING","PROTECTED","FAILED","NOT_ENCRYPTED","MISSING_RECOVERY_KEY","ENCRYPTED","ACTION_REQUIRED","GRACE_PERIOD","UP_TO_DATE","NOT_UP_TO_DATE","ENFORCED","ERROR","CREATION_PENDING","DEMOTION_PENDING","CREATED","CREATION_FAILED","SUCCESS","UNSUPPORTED","INSTALLED","MDM_ON","MDM_OFF","MDM_ON_IN_ANOTHER_MDM","READY_ZTD","MISSING_AGENT","ONLINE","OFFLINE","ENABLED","DISABLED","MISSING_BYPASS_CODE","MEETS_REQUIREMENTS","BELOW_MINIMUM_VERSION","UNSUPPORTED_OS_EDITION"]},"additionalStatus":{"description":"Narrows `status` when several situations share it. Null when `status` already says everything — a compliant device, or a status only one situation can produce — and on rows computed before this field existed. PROFILE_DELIVERY_PENDING: The MDM profile is queued for delivery; the device has not acknowledged it yet. PROFILE_VERIFYING: The MDM profile was installed and the MDM is verifying it applied. PROFILE_NOT_ON_DEVICE: The MDM has no record of this profile on the device; it was never scoped to it. A resend needs a prior delivery, so refresh the device and re-check the control targeting instead. PROFILE_DELIVERY_FAILED: The device rejected the MDM profile. `detail` carries the MDM error. CONTROL_MISSING_PROFILE: The control has no profile to deploy; this is a Primo configuration issue, not a device issue. POLICY_NOT_EVALUATED: The device has not reported a result for the compliance check yet. POLICY_NOT_ON_DEVICE: The compliance check is not attached to this device in the MDM. POLICY_FAILED: The compliance check attached to the control fails on the device. CONTROL_MISSING_POLICY: The control has no compliance check attached; this is a Primo configuration issue. RECOVERY_OS_STATUS_UNKNOWN: Primo has not computed the recovery OS state of this device yet. RECOVERY_OS_PROTECTION_PENDING: The recovery OS password command was sent and awaits the device. RECOVERY_OS_PROTECTION_FAILED: The device rejected the recovery OS password command. RECOVERY_OS_NOT_PROTECTED: Recovery OS has no password set. RECOVERY_OS_STATUS_UNRECOGNIZED: The device reports a recovery OS state Primo does not know. `detail` carries the raw value. SENTINEL_ONE_AGENT_NOT_INSTALLED: The SentinelOne agent is not installed on the device. SENTINEL_ONE_AGENT_INSTALLED_NOT_REGISTERED: The SentinelOne agent is installed but the device is not registered in the SentinelOne console. MALWAREBYTES_AGENT_NOT_INSTALLED: The Malwarebytes agent is not in the device software inventory and no install ran in the last 24 hours. MALWAREBYTES_INSTALL_IN_PROGRESS: The Malwarebytes install script ran in the last 24 hours; wait for the next inventory sync. `detail` carries the run date. MALWAREBYTES_ENDPOINT_NOT_FOUND: The Malwarebytes agent is installed but the device has no endpoint in the Malwarebytes console; the agent is not registered to the company account. MALWAREBYTES_REGISTRATION_IN_PROGRESS: The Malwarebytes registration script ran in the last hour; wait for the console to sync. `detail` carries the run date. MALWAREBYTES_ENDPOINT_UNPROTECTED: The device exists in the Malwarebytes console but is not protected. `detail` carries the console protection status. MALWAREBYTES_AGENT_NEVER_REPORTED: The Malwarebytes console has no activity date for this device. MALWAREBYTES_AGENT_INACTIVE: The Malwarebytes agent last reported more than 7 days ago. `detail` carries the last activity date. RUSTDESK_INSTALL_NOT_STARTED: No RustDesk installation was recorded for this device yet. RUSTDESK_INSTALL_IN_PROGRESS: The RustDesk installation is in progress. RUSTDESK_INSTALL_FAILED: The RustDesk installation failed on the device. ADMIN_ACCOUNT_CREATION_QUEUED: The managed admin account creation is queued: no creation command has been dispatched to this device yet. ADMIN_ACCOUNT_CREATION_IN_PROGRESS: The managed admin account creation was dispatched and awaits the device. ADMIN_ACCOUNT_PRE_EXISTING: An account with the policy username already exists on the device and was not created by Primo. `detail` carries the username. NO_MANAGED_ADMIN_TO_ROTATE: No local admin account with the policy username exists on the device, nothing to rotate. PASSWORD_ROTATION_UP_TO_DATE: The admin password was rotated within the configured frequency. ADMIN_PASSWORD_UNKNOWN: The admin account was not created by Primo and Primo does not hold its password yet: the next rotation replaces it. `detail` carries the username. NO_SECURE_TOKEN_ADMIN_TO_ROTATE: macOS only: Primo cannot change this password. A reset needs another local admin holding a SecureToken whose password Primo stores, and the device has none. `detail` carries the username. DEVICE_NAME_SUGGESTION_NOT_GENERATED: Primo has not generated the expected name for this device yet. `detail` carries the last failed attempt, if any. DEVICE_NAME_ALREADY_USED: Primo gave up naming this device: the name its rule produces is held by another device of the company. `detail` carries the name and the id of that device — retire it or rename it, then regenerate the name. DEVICE_NAME_SUGGESTION_FAILED: Primo gave up naming this device after repeated invalid AI outputs. `detail` carries the failure type; regenerate the name once the rule is fixed. DEVICE_RENAME_NOT_DISPATCHED: The device name differs from the convention and no rename command is in flight. `detail` carries expected vs actual. DEVICE_RENAME_COMMAND_IN_PROGRESS: A rename command was sent and awaits the device. `detail` carries expected vs actual. DEVICE_OFFLINE_LESS_THAN_7_DAYS: The device has not checked in for less than 7 days. `detail` carries the last check-in. DEVICE_LAST_SEEN_UNKNOWN: The MDM reports no valid last check-in date for this device.","anyOf":[{"type":"string","enum":["MALWAREBYTES_AGENT_NOT_INSTALLED","MALWAREBYTES_INSTALL_IN_PROGRESS","MALWAREBYTES_ENDPOINT_NOT_FOUND","MALWAREBYTES_REGISTRATION_IN_PROGRESS","MALWAREBYTES_ENDPOINT_UNPROTECTED","MALWAREBYTES_AGENT_NEVER_REPORTED","MALWAREBYTES_AGENT_INACTIVE","RECOVERY_OS_STATUS_UNKNOWN","RECOVERY_OS_PROTECTION_PENDING","RECOVERY_OS_PROTECTION_FAILED","RECOVERY_OS_NOT_PROTECTED","RECOVERY_OS_STATUS_UNRECOGNIZED","PROFILE_DELIVERY_PENDING","PROFILE_VERIFYING","PROFILE_NOT_ON_DEVICE","PROFILE_DELIVERY_FAILED","CONTROL_MISSING_PROFILE","POLICY_NOT_EVALUATED","POLICY_NOT_ON_DEVICE","POLICY_FAILED","CONTROL_MISSING_POLICY","ADMIN_ACCOUNT_CREATION_QUEUED","ADMIN_ACCOUNT_CREATION_IN_PROGRESS","ADMIN_ACCOUNT_PRE_EXISTING","NO_MANAGED_ADMIN_TO_ROTATE","PASSWORD_ROTATION_UP_TO_DATE","ADMIN_PASSWORD_UNKNOWN","NO_SECURE_TOKEN_ADMIN_TO_ROTATE","DEVICE_NAME_SUGGESTION_NOT_GENERATED","DEVICE_NAME_ALREADY_USED","DEVICE_NAME_SUGGESTION_FAILED","DEVICE_RENAME_NOT_DISPATCHED","DEVICE_RENAME_COMMAND_IN_PROGRESS","SENTINEL_ONE_AGENT_NOT_INSTALLED","SENTINEL_ONE_AGENT_INSTALLED_NOT_REGISTERED","RUSTDESK_INSTALL_NOT_STARTED","RUSTDESK_INSTALL_IN_PROGRESS","RUSTDESK_INSTALL_FAILED","DEVICE_OFFLINE_LESS_THAN_7_DAYS","DEVICE_LAST_SEEN_UNKNOWN"]},{"type":"null"}]},"detail":{"description":"Raw evidence behind `additionalStatus` when one exists (an MDM error, an upstream protection status, a date, a name). Human readable, not stable.","anyOf":[{"type":"string"},{"type":"null"}]},"hasAlert":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"description":"When the compliance of the device was last checked.","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"statusSince":{"description":"When the device was first observed carrying the current status. Resets on every status change, including between two non-compliant statuses. Null until the device syncs for the first time.","anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]}},"required":["id","deviceId","deviceName","devicePlatform","owner","complianceRuleId","ruleType","mdmControlId","status","additionalStatus","detail","hasAlert","createdAt","updatedAt","statusSince"],"additionalProperties":false},"mdmControl":{"description":"The MDM control behind the alert — null for built-in checks (enrollment, online, iCloud lock, Primo requirement).","anyOf":[{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"category":{"type":"string"},"type":{"type":"string"},"identifier":{"type":"string"},"enabled":{"type":"boolean"},"profileFleetId":{"description":"MDM identifier of the profile this control deploys — matches an entry of device.fleet.profiles.","anyOf":[{"type":"string"},{"type":"null"}]},"configurationPayload":{"description":"The Primo configuration the control enforces on the device, secret values included.","anyOf":[{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},{"type":"null"}]}},"required":["id","name","category","type","identifier","enabled","profileFleetId","configurationPayload"],"additionalProperties":false},{"type":"null"}]},"device":{"type":"object","properties":{"fleet":{"description":"Live MDM state of the device — null when the device is no longer enrolled, or when your company has no MDM instance to read it from.","anyOf":[{"type":"object","properties":{"fleetHostId":{"description":"MDM identifier of the host — the join key for MDM operations.","type":"number"},"uuid":{"type":"string"},"displayName":{"type":"string"},"hardwareSerial":{"description":"Can be an empty string — never use it as a join key.","type":"string"},"status":{"description":"Liveness — caps any device-side remediation.","type":"string","enum":["online","offline","missing","new"]},"seenTime":{"description":"When the device last checked in.","type":"string"},"detailUpdatedAt":{"description":"How fresh the inventory below is.","anyOf":[{"type":"string"},{"type":"null"}]},"refetchRequested":{"description":"True when a refresh of this host is already queued.","type":"boolean"},"uptime":{"description":"Nanoseconds since boot.","anyOf":[{"type":"number"},{"type":"null"}]},"lastRestartedAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"orbitVersion":{"description":"null means the device does not run the MDM agent.","anyOf":[{"type":"string"},{"type":"null"}]},"platform":{"description":"Raw MDM platform: darwin | windows | ubuntu | debian | fedora…","type":"string"},"osVersion":{"type":"string"},"build":{"anyOf":[{"type":"string"},{"type":"null"}]},"codeName":{"description":"OS code name; the edition string on Windows.","anyOf":[{"type":"string"},{"type":"null"}]},"gigsDiskSpaceAvailable":{"description":"Absolute free space in GB.","anyOf":[{"type":"number"},{"type":"null"}]},"mdm":{"type":"object","properties":{"enrollmentStatus":{"anyOf":[{"type":"string"},{"type":"null"}]},"name":{"anyOf":[{"type":"string"},{"type":"null"}]},"serverUrl":{"anyOf":[{"type":"string"},{"type":"null"}]},"connectedToFleet":{"type":"boolean"},"depProfileError":{"type":"boolean"},"deviceStatus":{"description":"unlocked | locked | wiped","anyOf":[{"type":"string"},{"type":"null"}]},"pendingAction":{"anyOf":[{"type":"string"},{"type":"null"}]},"lastEnrolledAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"lastMdmEnrolledAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"lastMdmCheckedInAt":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["enrollmentStatus","name","serverUrl","connectedToFleet","depProfileError","deviceStatus","pendingAction","lastEnrolledAt","lastMdmEnrolledAt","lastMdmCheckedInAt"],"additionalProperties":false},"encryption":{"type":"object","properties":{"diskEncryptionEnabled":{"anyOf":[{"type":"boolean"},{"type":"null"}]},"encryptionKeyAvailable":{"description":"Whether a recovery key is escrowed. The key itself is never returned.","anyOf":[{"type":"boolean"},{"type":"null"}]},"osSettingsStatus":{"description":"verified | verifying | pending | action_required | failed","anyOf":[{"type":"string"},{"type":"null"}]},"osSettingsDetail":{"description":"The root cause when encryption is not verified.","anyOf":[{"type":"string"},{"type":"null"}]},"appleActionRequired":{"description":"What FileVault is waiting for on a Mac. `log_out` and `rotate_key`: the end user logs out and back in. `turn_on_encryption`: the key is set to be escrowed but FileVault is not enforced and the disk is not encrypted, so no prompt reaches the end user; it is an admin setting to change.","anyOf":[{"type":"string","enum":["rotate_key","log_out","turn_on_encryption"]},{"type":"null"}]}},"required":["diskEncryptionEnabled","encryptionKeyAvailable","osSettingsStatus","osSettingsDetail","appleActionRequired"],"additionalProperties":false},"profiles":{"description":"All configuration profiles and their delivery status.","type":"array","items":{"type":"object","properties":{"profileUuid":{"description":"MDM identifier of the profile. Not a valid UUID despite the name — pass verbatim.","type":"string"},"name":{"type":"string"},"status":{"description":"MDM delivery status of the profile on the device.","anyOf":[{"type":"string","enum":["verified","verifying","pending","failed"]},{"type":"null"}]},"operationType":{"anyOf":[{"type":"string","enum":["install","remove"]},{"type":"null"}]},"detail":{"description":"Delivery error detail reported by MDM when the profile failed.","type":"string"},"scope":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["profileUuid","name","status","operationType","detail","scope"],"additionalProperties":false}},"labelNames":{"description":"MDM label names the device belongs to.","type":"array","items":{"type":"string"}},"idpUsername":{"description":"Identity-provider account the MDM associates with the device.","anyOf":[{"type":"string"},{"type":"null"}]},"idpFullName":{"anyOf":[{"type":"string"},{"type":"null"}]},"bootstrapPackageStatus":{"anyOf":[{"type":"string"},{"type":"null"}]},"bootstrapPackageDetail":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["fleetHostId","uuid","displayName","hardwareSerial","status","seenTime","detailUpdatedAt","refetchRequested","uptime","lastRestartedAt","orbitVersion","platform","osVersion","build","codeName","gigsDiskSpaceAvailable","mdm","encryption","profiles","labelNames","idpUsername","idpFullName","bootstrapPackageStatus","bootstrapPackageDetail"],"additionalProperties":false},{"type":"null"}]},"primo":{"description":"Device state Primo tracks itself, outside of MDM.","type":"object","properties":{"scriptsEnabled":{"description":"Whether MDM scripts can run on the device — null when unknown. Primo-verified, not the unreliable agent-reported flag: no script remediation when false.","anyOf":[{"type":"boolean"},{"type":"null"}]},"naming":{"description":"Expected versus actual device naming — the gap is what a deviceNaming alert reports.","anyOf":[{"type":"object","properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}]},"computerName":{"anyOf":[{"type":"string"},{"type":"null"}]},"hostname":{"anyOf":[{"type":"string"},{"type":"null"}]},"computerNameSuggestion":{"anyOf":[{"type":"string"},{"type":"null"}]},"hostnameSuggestion":{"anyOf":[{"type":"string"},{"type":"null"}]},"mdmCommandInProgress":{"anyOf":[{"type":"boolean"},{"type":"null"}]},"lastMDMCommandRunAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"aiSuggestionFailure":{"description":"Why Primo could not generate the expected name — null when it never failed. After 3 attempts it stops trying; on NAME_COLLISION, conflictingDeviceId is the device holding attemptedName.","anyOf":[{"type":"object","properties":{"attempts":{"type":"number"},"lastAttemptAt":{"type":"string"},"failureType":{"anyOf":[{"type":"string","enum":["EMPTY_OUTPUT","NAME_COLLISION","SCHEMA_PARSE_ERROR"]},{"type":"null"}]},"attemptedName":{"anyOf":[{"type":"string"},{"type":"null"}]},"conflictingDeviceId":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["attempts","lastAttemptAt","failureType","attemptedName","conflictingDeviceId"],"additionalProperties":false},{"type":"null"}]}},"required":["name","computerName","hostname","computerNameSuggestion","hostnameSuggestion","mdmCommandInProgress","lastMDMCommandRunAt","aiSuggestionFailure"],"additionalProperties":false},{"type":"null"}]},"malwarebytes":{"anyOf":[{"type":"object","properties":{"protectionStatus":{"anyOf":[{"type":"string"},{"type":"null"}]},"hasAgentInstalled":{"type":"boolean"},"hasAlerts":{"type":"boolean"},"lastActive":{"anyOf":[{"type":"string"},{"type":"null"}]},"lastScriptRunAt":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["protectionStatus","hasAgentInstalled","hasAlerts","lastActive","lastScriptRunAt"],"additionalProperties":false},{"type":"null"}]},"sentinelOne":{"anyOf":[{"type":"object","properties":{"installed":{"anyOf":[{"type":"boolean"},{"type":"null"}]},"registeredAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"lastActiveDate":{"anyOf":[{"type":"string"},{"type":"null"}]},"scanFinishedAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"uninstalledAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"infected":{"anyOf":[{"type":"boolean"},{"type":"null"}]}},"required":["installed","registeredAt","lastActiveDate","scanFinishedAt","uninstalledAt","infected"],"additionalProperties":false},{"type":"null"}]},"encryption":{"anyOf":[{"type":"object","properties":{"encrypted":{"anyOf":[{"type":"boolean"},{"type":"null"}]},"recoveryKeyRemotelyAvailable":{"anyOf":[{"type":"boolean"},{"type":"null"}]}},"required":["encrypted","recoveryKeyRemotelyAvailable"],"additionalProperties":false},{"type":"null"}]},"recoveryOsStatus":{"anyOf":[{"type":"string"},{"type":"null"}]},"localUsers":{"description":"Local accounts on the device, with their creation status and password-rotation state.","type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"username":{"type":"string"},"rights":{"type":"string"},"accountType":{"type":"string"},"creationStatus":{"anyOf":[{"type":"string"},{"type":"null"}]},"creationSource":{"type":"string"},"groupName":{"anyOf":[{"type":"string"},{"type":"null"}]},"passwordChangePending":{"anyOf":[{"type":"boolean"},{"type":"null"}]},"passwordChangedAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"createdAt":{"type":"string"}},"required":["id","username","rights","accountType","creationStatus","creationSource","groupName","passwordChangePending","passwordChangedAt","createdAt"],"additionalProperties":false}}},"required":["scriptsEnabled","naming","malwarebytes","sentinelOne","encryption","recoveryOsStatus","localUsers"],"additionalProperties":false}},"required":["fleet","primo"],"additionalProperties":false},"enforcement":{"type":"object","description":"How this control is enforced on this device. A key is present only when the control carries that artifact, and a control can carry several. All keys absent means the enforcement happens outside MDM — read `device.primo`.","properties":{"profile":{"type":"object","properties":{"fleetId":{"type":"string"},"resendable":{"description":"Whether resendDeviceProfile would be accepted for this profile right now — false for a declaration (which has no per-device redelivery) and while a delivery is already in flight (pending / verifying).","type":"boolean"},"delivery":{"description":"Delivery state of the profile enforcing this control on this device — null when the profile never reached the device.","anyOf":[{"type":"object","properties":{"profileUuid":{"description":"MDM identifier of the profile. Not a valid UUID despite the name — pass verbatim.","type":"string"},"name":{"type":"string"},"status":{"description":"MDM delivery status of the profile on the device.","anyOf":[{"type":"string","enum":["verified","verifying","pending","failed"]},{"type":"null"}]},"operationType":{"anyOf":[{"type":"string","enum":["install","remove"]},{"type":"null"}]},"detail":{"description":"Delivery error detail reported by MDM when the profile failed.","type":"string"},"scope":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["profileUuid","name","status","operationType","detail","scope"],"additionalProperties":false},{"type":"null"}]},"content":{"description":"The rendered configuration profile deployed to the device.","anyOf":[{"type":"string"},{"type":"null"}]}},"required":["fleetId","resendable","delivery","content"],"additionalProperties":false},"script":{"type":"object","properties":{"scriptId":{"anyOf":[{"type":"number"},{"type":"null"}]},"source":{"description":"The enforcement script deployed to the device.","anyOf":[{"type":"string"},{"type":"null"}]},"lastExecution":{"anyOf":[{"type":"object","properties":{"status":{"type":"string","enum":["ran","pending","error"]},"executedAt":{"type":"string"},"exitCode":{"anyOf":[{"type":"number"},{"type":"null"}]},"output":{"description":"Tail of the script output (truncated).","anyOf":[{"type":"string"},{"type":"null"}]}},"required":["status","executedAt","exitCode","output"],"additionalProperties":false},{"type":"null"}]},"policies":{"description":"Compliance checks attached to this control.","type":"array","items":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string"},"query":{"description":"The osquery check evaluated on the device.","type":"string"},"resolution":{"anyOf":[{"type":"string"},{"type":"null"}]},"response":{"description":"Latest device response for the check — empty or null when not yet evaluated.","anyOf":[{"type":"string","enum":["pass","fail",""]},{"type":"null"}]}},"required":["id","name","query","resolution","response"],"additionalProperties":false}}},"required":["scriptId","source","lastExecution","policies"],"additionalProperties":false},"software":{"type":"object","properties":{"appId":{"description":"The software this control installs — inspect it with getDeviceSoftware.","type":"string"},"install":{"description":"Install state of that software on this device — null when no install record exists.","anyOf":[{"type":"object","properties":{"softwareId":{"type":"string"},"softwareName":{"type":"string"},"status":{"type":"string","enum":["installed","failed","in_progress","not_installed"]},"installedVersion":{"anyOf":[{"type":"string"},{"type":"null"}]},"availableVersion":{"anyOf":[{"type":"string"},{"type":"null"}]},"lastInstalledAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]}},"required":["softwareId","softwareName","status","installedVersion","availableVersion","lastInstalledAt"],"additionalProperties":false},{"type":"null"}]}},"required":["appId","install"],"additionalProperties":false},"command":{"type":"object","properties":{"id":{"type":"string"},"command":{"type":"string"},"status":{"type":"string"},"type":{"anyOf":[{"type":"string"},{"type":"null"}]},"source":{"type":"string"},"initiator":{"type":"string"},"remoteId":{"anyOf":[{"type":"string"},{"type":"null"}]},"payload":{"description":"What was sent to the device — the script itself for script commands."},"result":{"description":"What the device answered."},"uuid":{"anyOf":[{"type":"string"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","command","status","type","source","initiator","remoteId","payload","result","uuid","createdAt","updatedAt"],"additionalProperties":false}},"additionalProperties":false}},"required":["alert","mdmControl","device","enforcement"],"additionalProperties":false},"GetComplianceAlertsDetailsBody":{"type":"object","properties":{"alertIds":{"description":"Identifiers of the compliance alerts, as returned by getComplianceAlerts or searchComplianceAlerts. Up to 25 per call.","minItems":1,"maxItems":25,"type":"array","items":{"type":"string","pattern":"^[a-f\\d]{24}$"}}},"required":["alertIds"]},"GetComplianceAlertsDetails_Output":{"type":"object","properties":{"items":{"type":"array","description":"The details of every alert found, in the order of `alertIds`.","items":{"type":"object","properties":{"alert":{"type":"object","properties":{"id":{"type":"string"},"deviceId":{"type":"string"},"deviceName":{"anyOf":[{"type":"string"},{"type":"null"}]},"devicePlatform":{"anyOf":[{"type":"string","enum":["ANDROID","IOS","IPADOS","MACOS","WINDOWS","LINUX","CHROME_OS","UNKNOWN"]},{"type":"null"}]},"owner":{"description":"Employee the alerting device is assigned to.","anyOf":[{"type":"object","properties":{"id":{"type":"string"},"firstName":{"type":"string"},"lastName":{"type":"string"}},"required":["id","firstName","lastName"],"additionalProperties":false},{"type":"null"}]},"complianceRuleId":{"type":"string"},"ruleType":{"description":"Type of the compliance rule behind the alert.","anyOf":[{"type":"string"},{"type":"null"}]},"mdmControlId":{"anyOf":[{"type":"string"},{"type":"null"}]},"status":{"type":"string","enum":["ACTIVE","NOT_PROTECTED","OFFLINE_7_DAYS","PENDING","PROTECTED","FAILED","NOT_ENCRYPTED","MISSING_RECOVERY_KEY","ENCRYPTED","ACTION_REQUIRED","GRACE_PERIOD","UP_TO_DATE","NOT_UP_TO_DATE","ENFORCED","ERROR","CREATION_PENDING","DEMOTION_PENDING","CREATED","CREATION_FAILED","SUCCESS","UNSUPPORTED","INSTALLED","MDM_ON","MDM_OFF","MDM_ON_IN_ANOTHER_MDM","READY_ZTD","MISSING_AGENT","ONLINE","OFFLINE","ENABLED","DISABLED","MISSING_BYPASS_CODE","MEETS_REQUIREMENTS","BELOW_MINIMUM_VERSION","UNSUPPORTED_OS_EDITION"]},"additionalStatus":{"description":"Narrows `status` when several situations share it. Null when `status` already says everything — a compliant device, or a status only one situation can produce — and on rows computed before this field existed. PROFILE_DELIVERY_PENDING: The MDM profile is queued for delivery; the device has not acknowledged it yet. PROFILE_VERIFYING: The MDM profile was installed and the MDM is verifying it applied. PROFILE_NOT_ON_DEVICE: The MDM has no record of this profile on the device; it was never scoped to it. A resend needs a prior delivery, so refresh the device and re-check the control targeting instead. PROFILE_DELIVERY_FAILED: The device rejected the MDM profile. `detail` carries the MDM error. CONTROL_MISSING_PROFILE: The control has no profile to deploy; this is a Primo configuration issue, not a device issue. POLICY_NOT_EVALUATED: The device has not reported a result for the compliance check yet. POLICY_NOT_ON_DEVICE: The compliance check is not attached to this device in the MDM. POLICY_FAILED: The compliance check attached to the control fails on the device. CONTROL_MISSING_POLICY: The control has no compliance check attached; this is a Primo configuration issue. RECOVERY_OS_STATUS_UNKNOWN: Primo has not computed the recovery OS state of this device yet. RECOVERY_OS_PROTECTION_PENDING: The recovery OS password command was sent and awaits the device. RECOVERY_OS_PROTECTION_FAILED: The device rejected the recovery OS password command. RECOVERY_OS_NOT_PROTECTED: Recovery OS has no password set. RECOVERY_OS_STATUS_UNRECOGNIZED: The device reports a recovery OS state Primo does not know. `detail` carries the raw value. SENTINEL_ONE_AGENT_NOT_INSTALLED: The SentinelOne agent is not installed on the device. SENTINEL_ONE_AGENT_INSTALLED_NOT_REGISTERED: The SentinelOne agent is installed but the device is not registered in the SentinelOne console. MALWAREBYTES_AGENT_NOT_INSTALLED: The Malwarebytes agent is not in the device software inventory and no install ran in the last 24 hours. MALWAREBYTES_INSTALL_IN_PROGRESS: The Malwarebytes install script ran in the last 24 hours; wait for the next inventory sync. `detail` carries the run date. MALWAREBYTES_ENDPOINT_NOT_FOUND: The Malwarebytes agent is installed but the device has no endpoint in the Malwarebytes console; the agent is not registered to the company account. MALWAREBYTES_REGISTRATION_IN_PROGRESS: The Malwarebytes registration script ran in the last hour; wait for the console to sync. `detail` carries the run date. MALWAREBYTES_ENDPOINT_UNPROTECTED: The device exists in the Malwarebytes console but is not protected. `detail` carries the console protection status. MALWAREBYTES_AGENT_NEVER_REPORTED: The Malwarebytes console has no activity date for this device. MALWAREBYTES_AGENT_INACTIVE: The Malwarebytes agent last reported more than 7 days ago. `detail` carries the last activity date. RUSTDESK_INSTALL_NOT_STARTED: No RustDesk installation was recorded for this device yet. RUSTDESK_INSTALL_IN_PROGRESS: The RustDesk installation is in progress. RUSTDESK_INSTALL_FAILED: The RustDesk installation failed on the device. ADMIN_ACCOUNT_CREATION_QUEUED: The managed admin account creation is queued: no creation command has been dispatched to this device yet. ADMIN_ACCOUNT_CREATION_IN_PROGRESS: The managed admin account creation was dispatched and awaits the device. ADMIN_ACCOUNT_PRE_EXISTING: An account with the policy username already exists on the device and was not created by Primo. `detail` carries the username. NO_MANAGED_ADMIN_TO_ROTATE: No local admin account with the policy username exists on the device, nothing to rotate. PASSWORD_ROTATION_UP_TO_DATE: The admin password was rotated within the configured frequency. ADMIN_PASSWORD_UNKNOWN: The admin account was not created by Primo and Primo does not hold its password yet: the next rotation replaces it. `detail` carries the username. NO_SECURE_TOKEN_ADMIN_TO_ROTATE: macOS only: Primo cannot change this password. A reset needs another local admin holding a SecureToken whose password Primo stores, and the device has none. `detail` carries the username. DEVICE_NAME_SUGGESTION_NOT_GENERATED: Primo has not generated the expected name for this device yet. `detail` carries the last failed attempt, if any. DEVICE_NAME_ALREADY_USED: Primo gave up naming this device: the name its rule produces is held by another device of the company. `detail` carries the name and the id of that device — retire it or rename it, then regenerate the name. DEVICE_NAME_SUGGESTION_FAILED: Primo gave up naming this device after repeated invalid AI outputs. `detail` carries the failure type; regenerate the name once the rule is fixed. DEVICE_RENAME_NOT_DISPATCHED: The device name differs from the convention and no rename command is in flight. `detail` carries expected vs actual. DEVICE_RENAME_COMMAND_IN_PROGRESS: A rename command was sent and awaits the device. `detail` carries expected vs actual. DEVICE_OFFLINE_LESS_THAN_7_DAYS: The device has not checked in for less than 7 days. `detail` carries the last check-in. DEVICE_LAST_SEEN_UNKNOWN: The MDM reports no valid last check-in date for this device.","anyOf":[{"type":"string","enum":["MALWAREBYTES_AGENT_NOT_INSTALLED","MALWAREBYTES_INSTALL_IN_PROGRESS","MALWAREBYTES_ENDPOINT_NOT_FOUND","MALWAREBYTES_REGISTRATION_IN_PROGRESS","MALWAREBYTES_ENDPOINT_UNPROTECTED","MALWAREBYTES_AGENT_NEVER_REPORTED","MALWAREBYTES_AGENT_INACTIVE","RECOVERY_OS_STATUS_UNKNOWN","RECOVERY_OS_PROTECTION_PENDING","RECOVERY_OS_PROTECTION_FAILED","RECOVERY_OS_NOT_PROTECTED","RECOVERY_OS_STATUS_UNRECOGNIZED","PROFILE_DELIVERY_PENDING","PROFILE_VERIFYING","PROFILE_NOT_ON_DEVICE","PROFILE_DELIVERY_FAILED","CONTROL_MISSING_PROFILE","POLICY_NOT_EVALUATED","POLICY_NOT_ON_DEVICE","POLICY_FAILED","CONTROL_MISSING_POLICY","ADMIN_ACCOUNT_CREATION_QUEUED","ADMIN_ACCOUNT_CREATION_IN_PROGRESS","ADMIN_ACCOUNT_PRE_EXISTING","NO_MANAGED_ADMIN_TO_ROTATE","PASSWORD_ROTATION_UP_TO_DATE","ADMIN_PASSWORD_UNKNOWN","NO_SECURE_TOKEN_ADMIN_TO_ROTATE","DEVICE_NAME_SUGGESTION_NOT_GENERATED","DEVICE_NAME_ALREADY_USED","DEVICE_NAME_SUGGESTION_FAILED","DEVICE_RENAME_NOT_DISPATCHED","DEVICE_RENAME_COMMAND_IN_PROGRESS","SENTINEL_ONE_AGENT_NOT_INSTALLED","SENTINEL_ONE_AGENT_INSTALLED_NOT_REGISTERED","RUSTDESK_INSTALL_NOT_STARTED","RUSTDESK_INSTALL_IN_PROGRESS","RUSTDESK_INSTALL_FAILED","DEVICE_OFFLINE_LESS_THAN_7_DAYS","DEVICE_LAST_SEEN_UNKNOWN"]},{"type":"null"}]},"detail":{"description":"Raw evidence behind `additionalStatus` when one exists (an MDM error, an upstream protection status, a date, a name). Human readable, not stable.","anyOf":[{"type":"string"},{"type":"null"}]},"hasAlert":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"description":"When the compliance of the device was last checked.","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"statusSince":{"description":"When the device was first observed carrying the current status. Resets on every status change, including between two non-compliant statuses. Null until the device syncs for the first time.","anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]}},"required":["id","deviceId","deviceName","devicePlatform","owner","complianceRuleId","ruleType","mdmControlId","status","additionalStatus","detail","hasAlert","createdAt","updatedAt","statusSince"],"additionalProperties":false},"mdmControl":{"description":"The MDM control behind the alert — null for built-in checks (enrollment, online, iCloud lock, Primo requirement).","anyOf":[{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"category":{"type":"string"},"type":{"type":"string"},"identifier":{"type":"string"},"enabled":{"type":"boolean"},"profileFleetId":{"description":"MDM identifier of the profile this control deploys — matches an entry of device.fleet.profiles.","anyOf":[{"type":"string"},{"type":"null"}]},"configurationPayload":{"description":"The Primo configuration the control enforces on the device, secret values included.","anyOf":[{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},{"type":"null"}]}},"required":["id","name","category","type","identifier","enabled","profileFleetId","configurationPayload"],"additionalProperties":false},{"type":"null"}]},"device":{"type":"object","properties":{"fleet":{"description":"Live MDM state of the device — null when the device is no longer enrolled, or when your company has no MDM instance to read it from.","anyOf":[{"type":"object","properties":{"fleetHostId":{"description":"MDM identifier of the host — the join key for MDM operations.","type":"number"},"uuid":{"type":"string"},"displayName":{"type":"string"},"hardwareSerial":{"description":"Can be an empty string — never use it as a join key.","type":"string"},"status":{"description":"Liveness — caps any device-side remediation.","type":"string","enum":["online","offline","missing","new"]},"seenTime":{"description":"When the device last checked in.","type":"string"},"detailUpdatedAt":{"description":"How fresh the inventory below is.","anyOf":[{"type":"string"},{"type":"null"}]},"refetchRequested":{"description":"True when a refresh of this host is already queued.","type":"boolean"},"uptime":{"description":"Nanoseconds since boot.","anyOf":[{"type":"number"},{"type":"null"}]},"lastRestartedAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"orbitVersion":{"description":"null means the device does not run the MDM agent.","anyOf":[{"type":"string"},{"type":"null"}]},"platform":{"description":"Raw MDM platform: darwin | windows | ubuntu | debian | fedora…","type":"string"},"osVersion":{"type":"string"},"build":{"anyOf":[{"type":"string"},{"type":"null"}]},"codeName":{"description":"OS code name; the edition string on Windows.","anyOf":[{"type":"string"},{"type":"null"}]},"gigsDiskSpaceAvailable":{"description":"Absolute free space in GB.","anyOf":[{"type":"number"},{"type":"null"}]},"mdm":{"type":"object","properties":{"enrollmentStatus":{"anyOf":[{"type":"string"},{"type":"null"}]},"name":{"anyOf":[{"type":"string"},{"type":"null"}]},"serverUrl":{"anyOf":[{"type":"string"},{"type":"null"}]},"connectedToFleet":{"type":"boolean"},"depProfileError":{"type":"boolean"},"deviceStatus":{"description":"unlocked | locked | wiped","anyOf":[{"type":"string"},{"type":"null"}]},"pendingAction":{"anyOf":[{"type":"string"},{"type":"null"}]},"lastEnrolledAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"lastMdmEnrolledAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"lastMdmCheckedInAt":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["enrollmentStatus","name","serverUrl","connectedToFleet","depProfileError","deviceStatus","pendingAction","lastEnrolledAt","lastMdmEnrolledAt","lastMdmCheckedInAt"],"additionalProperties":false},"encryption":{"type":"object","properties":{"diskEncryptionEnabled":{"anyOf":[{"type":"boolean"},{"type":"null"}]},"encryptionKeyAvailable":{"description":"Whether a recovery key is escrowed. The key itself is never returned.","anyOf":[{"type":"boolean"},{"type":"null"}]},"osSettingsStatus":{"description":"verified | verifying | pending | action_required | failed","anyOf":[{"type":"string"},{"type":"null"}]},"osSettingsDetail":{"description":"The root cause when encryption is not verified.","anyOf":[{"type":"string"},{"type":"null"}]},"appleActionRequired":{"description":"What FileVault is waiting for on a Mac. `log_out` and `rotate_key`: the end user logs out and back in. `turn_on_encryption`: the key is set to be escrowed but FileVault is not enforced and the disk is not encrypted, so no prompt reaches the end user; it is an admin setting to change.","anyOf":[{"type":"string","enum":["rotate_key","log_out","turn_on_encryption"]},{"type":"null"}]}},"required":["diskEncryptionEnabled","encryptionKeyAvailable","osSettingsStatus","osSettingsDetail","appleActionRequired"],"additionalProperties":false},"profiles":{"description":"All configuration profiles and their delivery status.","type":"array","items":{"type":"object","properties":{"profileUuid":{"description":"MDM identifier of the profile. Not a valid UUID despite the name — pass verbatim.","type":"string"},"name":{"type":"string"},"status":{"description":"MDM delivery status of the profile on the device.","anyOf":[{"type":"string","enum":["verified","verifying","pending","failed"]},{"type":"null"}]},"operationType":{"anyOf":[{"type":"string","enum":["install","remove"]},{"type":"null"}]},"detail":{"description":"Delivery error detail reported by MDM when the profile failed.","type":"string"},"scope":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["profileUuid","name","status","operationType","detail","scope"],"additionalProperties":false}},"labelNames":{"description":"MDM label names the device belongs to.","type":"array","items":{"type":"string"}},"idpUsername":{"description":"Identity-provider account the MDM associates with the device.","anyOf":[{"type":"string"},{"type":"null"}]},"idpFullName":{"anyOf":[{"type":"string"},{"type":"null"}]},"bootstrapPackageStatus":{"anyOf":[{"type":"string"},{"type":"null"}]},"bootstrapPackageDetail":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["fleetHostId","uuid","displayName","hardwareSerial","status","seenTime","detailUpdatedAt","refetchRequested","uptime","lastRestartedAt","orbitVersion","platform","osVersion","build","codeName","gigsDiskSpaceAvailable","mdm","encryption","profiles","labelNames","idpUsername","idpFullName","bootstrapPackageStatus","bootstrapPackageDetail"],"additionalProperties":false},{"type":"null"}]},"primo":{"description":"Device state Primo tracks itself, outside of MDM.","type":"object","properties":{"scriptsEnabled":{"description":"Whether MDM scripts can run on the device — null when unknown. Primo-verified, not the unreliable agent-reported flag: no script remediation when false.","anyOf":[{"type":"boolean"},{"type":"null"}]},"naming":{"description":"Expected versus actual device naming — the gap is what a deviceNaming alert reports.","anyOf":[{"type":"object","properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}]},"computerName":{"anyOf":[{"type":"string"},{"type":"null"}]},"hostname":{"anyOf":[{"type":"string"},{"type":"null"}]},"computerNameSuggestion":{"anyOf":[{"type":"string"},{"type":"null"}]},"hostnameSuggestion":{"anyOf":[{"type":"string"},{"type":"null"}]},"mdmCommandInProgress":{"anyOf":[{"type":"boolean"},{"type":"null"}]},"lastMDMCommandRunAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"aiSuggestionFailure":{"description":"Why Primo could not generate the expected name — null when it never failed. After 3 attempts it stops trying; on NAME_COLLISION, conflictingDeviceId is the device holding attemptedName.","anyOf":[{"type":"object","properties":{"attempts":{"type":"number"},"lastAttemptAt":{"type":"string"},"failureType":{"anyOf":[{"type":"string","enum":["EMPTY_OUTPUT","NAME_COLLISION","SCHEMA_PARSE_ERROR"]},{"type":"null"}]},"attemptedName":{"anyOf":[{"type":"string"},{"type":"null"}]},"conflictingDeviceId":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["attempts","lastAttemptAt","failureType","attemptedName","conflictingDeviceId"],"additionalProperties":false},{"type":"null"}]}},"required":["name","computerName","hostname","computerNameSuggestion","hostnameSuggestion","mdmCommandInProgress","lastMDMCommandRunAt","aiSuggestionFailure"],"additionalProperties":false},{"type":"null"}]},"malwarebytes":{"anyOf":[{"type":"object","properties":{"protectionStatus":{"anyOf":[{"type":"string"},{"type":"null"}]},"hasAgentInstalled":{"type":"boolean"},"hasAlerts":{"type":"boolean"},"lastActive":{"anyOf":[{"type":"string"},{"type":"null"}]},"lastScriptRunAt":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["protectionStatus","hasAgentInstalled","hasAlerts","lastActive","lastScriptRunAt"],"additionalProperties":false},{"type":"null"}]},"sentinelOne":{"anyOf":[{"type":"object","properties":{"installed":{"anyOf":[{"type":"boolean"},{"type":"null"}]},"registeredAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"lastActiveDate":{"anyOf":[{"type":"string"},{"type":"null"}]},"scanFinishedAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"uninstalledAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"infected":{"anyOf":[{"type":"boolean"},{"type":"null"}]}},"required":["installed","registeredAt","lastActiveDate","scanFinishedAt","uninstalledAt","infected"],"additionalProperties":false},{"type":"null"}]},"encryption":{"anyOf":[{"type":"object","properties":{"encrypted":{"anyOf":[{"type":"boolean"},{"type":"null"}]},"recoveryKeyRemotelyAvailable":{"anyOf":[{"type":"boolean"},{"type":"null"}]}},"required":["encrypted","recoveryKeyRemotelyAvailable"],"additionalProperties":false},{"type":"null"}]},"recoveryOsStatus":{"anyOf":[{"type":"string"},{"type":"null"}]},"localUsers":{"description":"Local accounts on the device, with their creation status and password-rotation state.","type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"username":{"type":"string"},"rights":{"type":"string"},"accountType":{"type":"string"},"creationStatus":{"anyOf":[{"type":"string"},{"type":"null"}]},"creationSource":{"type":"string"},"groupName":{"anyOf":[{"type":"string"},{"type":"null"}]},"passwordChangePending":{"anyOf":[{"type":"boolean"},{"type":"null"}]},"passwordChangedAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"createdAt":{"type":"string"}},"required":["id","username","rights","accountType","creationStatus","creationSource","groupName","passwordChangePending","passwordChangedAt","createdAt"],"additionalProperties":false}}},"required":["scriptsEnabled","naming","malwarebytes","sentinelOne","encryption","recoveryOsStatus","localUsers"],"additionalProperties":false}},"required":["fleet","primo"],"additionalProperties":false},"enforcement":{"description":"How this control is enforced on this device. A key is present only when the control carries that artifact, and a control can carry several. All keys absent means the enforcement happens outside MDM — read `device.primo`.","type":"object","properties":{"profile":{"type":"object","properties":{"fleetId":{"type":"string"},"resendable":{"description":"Whether resendDeviceProfile would be accepted for this profile right now — false for a declaration (which has no per-device redelivery) and while a delivery is already in flight (pending / verifying).","type":"boolean"},"delivery":{"description":"Delivery state of the profile enforcing this control on this device — null when the profile never reached the device.","anyOf":[{"type":"object","properties":{"profileUuid":{"description":"MDM identifier of the profile. Not a valid UUID despite the name — pass verbatim.","type":"string"},"name":{"type":"string"},"status":{"description":"MDM delivery status of the profile on the device.","anyOf":[{"type":"string","enum":["verified","verifying","pending","failed"]},{"type":"null"}]},"operationType":{"anyOf":[{"type":"string","enum":["install","remove"]},{"type":"null"}]},"detail":{"description":"Delivery error detail reported by MDM when the profile failed.","type":"string"},"scope":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["profileUuid","name","status","operationType","detail","scope"],"additionalProperties":false},{"type":"null"}]},"content":{"description":"The rendered configuration profile deployed to the device.","anyOf":[{"type":"string"},{"type":"null"}]}},"required":["fleetId","resendable","delivery","content"],"additionalProperties":false},"script":{"type":"object","properties":{"scriptId":{"anyOf":[{"type":"number"},{"type":"null"}]},"source":{"description":"The enforcement script deployed to the device.","anyOf":[{"type":"string"},{"type":"null"}]},"lastExecution":{"anyOf":[{"type":"object","properties":{"status":{"type":"string","enum":["ran","pending","error"]},"executedAt":{"type":"string"},"exitCode":{"anyOf":[{"type":"number"},{"type":"null"}]},"output":{"description":"Tail of the script output (truncated).","anyOf":[{"type":"string"},{"type":"null"}]}},"required":["status","executedAt","exitCode","output"],"additionalProperties":false},{"type":"null"}]},"policies":{"description":"Compliance checks attached to this control.","type":"array","items":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string"},"query":{"description":"The osquery check evaluated on the device.","type":"string"},"resolution":{"anyOf":[{"type":"string"},{"type":"null"}]},"response":{"description":"Latest device response for the check — empty or null when not yet evaluated.","anyOf":[{"type":"string","enum":["pass","fail",""]},{"type":"null"}]}},"required":["id","name","query","resolution","response"],"additionalProperties":false}}},"required":["scriptId","source","lastExecution","policies"],"additionalProperties":false},"software":{"type":"object","properties":{"appId":{"description":"The software this control installs — inspect it with getDeviceSoftware.","type":"string"},"install":{"description":"Install state of that software on this device — null when no install record exists.","anyOf":[{"type":"object","properties":{"softwareId":{"type":"string"},"softwareName":{"type":"string"},"status":{"type":"string","enum":["installed","failed","in_progress","not_installed"]},"installedVersion":{"anyOf":[{"type":"string"},{"type":"null"}]},"availableVersion":{"anyOf":[{"type":"string"},{"type":"null"}]},"lastInstalledAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]}},"required":["softwareId","softwareName","status","installedVersion","availableVersion","lastInstalledAt"],"additionalProperties":false},{"type":"null"}]}},"required":["appId","install"],"additionalProperties":false},"command":{"type":"object","properties":{"id":{"type":"string"},"command":{"type":"string"},"status":{"type":"string"},"type":{"anyOf":[{"type":"string"},{"type":"null"}]},"source":{"type":"string"},"initiator":{"type":"string"},"remoteId":{"anyOf":[{"type":"string"},{"type":"null"}]},"payload":{"description":"What was sent to the device — the script itself for script commands."},"result":{"description":"What the device answered."},"uuid":{"anyOf":[{"type":"string"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","command","status","type","source","initiator","remoteId","payload","result","uuid","createdAt","updatedAt"],"additionalProperties":false}},"additionalProperties":false}},"required":["alert","mdmControl","device","enforcement"],"additionalProperties":false}},"notFoundAlertIds":{"type":"array","description":"The requested ids that match no compliance alert of your company: the check no longer applies to that device. Asking again returns them here again.","items":{"type":"string"}}},"required":["items","notFoundAlertIds"],"additionalProperties":false},"GetComplianceAlertsFilterCatalog_Output":{"type":"object","properties":{"filterOptions":{"type":"array","description":"Every criterion the compliance alert list accepts. Build the `filter` of getComplianceAlerts by placing, under each option's `key`, a clause { operationType, values }.","items":{"type":"object","properties":{"key":{"description":"The key to use in the `filter` object of `getComplianceAlerts`.","type":"string"},"kind":{"description":"Compliance alert criteria are all native — there are no custom fields here.","type":"string","const":"native"},"valueType":{"description":"How many values the clause accepts: multiple, exactly one, or a boolean flag.","type":"string","enum":["multi_select","single_select","flag"]},"operationTypes":{"description":"The values allowed for the clause's `operationType` field. A clause is written as { operationType: <one of these>, values: [...] } under this option's `key`.","type":"array","items":{"type":"string","enum":["INCLUDE","EXCLUDE"]}},"supportsEmpty":{"description":"Whether this criterion can match the \"unset\" case.","type":"boolean"},"description":{"description":"Human-readable description of what this criterion filters on.","type":"string"},"values":{"description":"The allowed values for this option, with live company data inline.","type":"array","items":{"description":"One allowed value of a filter option.","type":"object","properties":{"value":{"description":"The raw value to write into the clause `values` array.","type":"string"},"label":{"description":"Human-readable label. For static enum values this equals `value`.","type":"string"}},"required":["value","label"],"additionalProperties":false}}},"required":["key","kind","valueType","operationTypes","supportsEmpty","description","values"],"additionalProperties":false}},"supportsMatchAny":{"type":"boolean","description":"Whether the filter supports OR across clauses. Criteria are ANDed when false."}},"required":["filterOptions","supportsMatchAny"],"additionalProperties":false},"GetComplianceAlertRules_Output":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string","enum":["MDM_CONTROL_MALWAREBYTES","MDM_CONTROL_RECOVERY_OS","MDM_CONTROL_ENCRYPTION","MDM_CONTROL_OS_UPDATE","MDM_CONTROL_SOFTWARE_UPDATE","MDM_CONTROL_WIFI","MDM_CONTROL_ADMIN_USER_MANAGEMENT","MDM_CONTROL_ADMIN_USER_PASSWORD_ROTATION","MDM_CONTROL_DEVICE_NAMING","MDM_CONTROL_GOOGLE_CHROME","MDM_CONTROL_FIREWALL","MDM_CONTROL_USB_BLOCKING","MDM_CONTROL_ENTRA_SSO","MDM_CONTROL_OKTA_SSO","MDM_CONTROL_CUSTOM_FILE","MDM_CONTROL_PASSWORD_POLICY","MDM_CONTROL_SENTINEL_ONE","MDM_CONTROL_RUSTDESK","MDM_CONTROL_APP_BLOCKING","MDM_CONTROL_DISABLE_PROFILES_PANE","MDM_CONTROL_DISABLE_AIRDROP","MDM_CONTROL_SCREEN_CAPTURE","MDM_CONTROL_AIR_PRINT","MDM_CONTROL_PRIMO_SSO","MDM_CONTROL_WEB_CLIP","MDM_ENROLLMENT","MDM_ONLINE","MDM_ICLOUD_LOCK_STATUS","PRIMO_REQUIREMENT"]},"nonCompliantStatus":{"description":"Statuses that raise a compliance issue (\"Create Issue\" or \"Create Issue and Ticket\" in the cockpit).","type":"array","items":{"type":"string","enum":["ACTIVE","NOT_PROTECTED","OFFLINE_7_DAYS","PENDING","PROTECTED","FAILED","NOT_ENCRYPTED","MISSING_RECOVERY_KEY","ENCRYPTED","ACTION_REQUIRED","GRACE_PERIOD","UP_TO_DATE","NOT_UP_TO_DATE","ENFORCED","ERROR","CREATION_PENDING","DEMOTION_PENDING","CREATED","CREATION_FAILED","SUCCESS","UNSUPPORTED","INSTALLED","MDM_ON","MDM_OFF","MDM_ON_IN_ANOTHER_MDM","READY_ZTD","MISSING_AGENT","ONLINE","OFFLINE","ENABLED","DISABLED","MISSING_BYPASS_CODE","MEETS_REQUIREMENTS","BELOW_MINIMUM_VERSION","UNSUPPORTED_OS_EDITION"]}},"ticketCreationStatus":{"description":"Among `nonCompliantStatus`, the statuses that also open a ticket (\"Create Issue and Ticket\"). A status in neither list is \"Off\".","type":"array","items":{"type":"string","enum":["ACTIVE","NOT_PROTECTED","OFFLINE_7_DAYS","PENDING","PROTECTED","FAILED","NOT_ENCRYPTED","MISSING_RECOVERY_KEY","ENCRYPTED","ACTION_REQUIRED","GRACE_PERIOD","UP_TO_DATE","NOT_UP_TO_DATE","ENFORCED","ERROR","CREATION_PENDING","DEMOTION_PENDING","CREATED","CREATION_FAILED","SUCCESS","UNSUPPORTED","INSTALLED","MDM_ON","MDM_OFF","MDM_ON_IN_ANOTHER_MDM","READY_ZTD","MISSING_AGENT","ONLINE","OFFLINE","ENABLED","DISABLED","MISSING_BYPASS_CODE","MEETS_REQUIREMENTS","BELOW_MINIMUM_VERSION","UNSUPPORTED_OS_EDITION"]}},"config":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"canEnable":{"description":"False for an MDM_CONTROL_* rule when no enabled MDM control of its category exists: its statuses cannot raise anything until such a control is enabled (see `getMdmControls`).","type":"boolean"}},"required":["id","type","nonCompliantStatus","ticketCreationStatus","config","createdAt","updatedAt","canEnable"],"additionalProperties":false}}},"required":["data"],"additionalProperties":false},"CreateComplianceAlertRuleBody":{"type":"object","properties":{"type":{"description":"Type of compliance rule (e.g. MDM_ENROLLMENT, MDM_ONLINE, MDM_CONTROL_ENCRYPTION). Each (company, type) pair is unique — creating a rule for an existing type overwrites it.","type":"string","enum":["MDM_CONTROL_MALWAREBYTES","MDM_CONTROL_RECOVERY_OS","MDM_CONTROL_ENCRYPTION","MDM_CONTROL_OS_UPDATE","MDM_CONTROL_SOFTWARE_UPDATE","MDM_CONTROL_WIFI","MDM_CONTROL_ADMIN_USER_MANAGEMENT","MDM_CONTROL_ADMIN_USER_PASSWORD_ROTATION","MDM_CONTROL_DEVICE_NAMING","MDM_CONTROL_GOOGLE_CHROME","MDM_CONTROL_FIREWALL","MDM_CONTROL_USB_BLOCKING","MDM_CONTROL_ENTRA_SSO","MDM_CONTROL_OKTA_SSO","MDM_CONTROL_CUSTOM_FILE","MDM_CONTROL_PASSWORD_POLICY","MDM_CONTROL_SENTINEL_ONE","MDM_CONTROL_RUSTDESK","MDM_CONTROL_APP_BLOCKING","MDM_CONTROL_DISABLE_PROFILES_PANE","MDM_CONTROL_DISABLE_AIRDROP","MDM_CONTROL_SCREEN_CAPTURE","MDM_CONTROL_AIR_PRINT","MDM_CONTROL_PRIMO_SSO","MDM_CONTROL_WEB_CLIP","MDM_ENROLLMENT","MDM_ONLINE","MDM_ICLOUD_LOCK_STATUS","PRIMO_REQUIREMENT"]},"nonCompliantStatus":{"description":"Non-compliant device statuses that should trigger an alert for this rule. Only non-compliant statuses are accepted (compliant statuses like SUCCESS, ONLINE, ENCRYPTED, etc. are rejected). Pass an empty array to disable alerts.","type":"array","items":{"type":"string","enum":["ACTIVE","NOT_PROTECTED","OFFLINE_7_DAYS","PENDING","PROTECTED","FAILED","NOT_ENCRYPTED","MISSING_RECOVERY_KEY","ENCRYPTED","ACTION_REQUIRED","GRACE_PERIOD","UP_TO_DATE","NOT_UP_TO_DATE","ENFORCED","ERROR","CREATION_PENDING","DEMOTION_PENDING","CREATED","CREATION_FAILED","SUCCESS","UNSUPPORTED","INSTALLED","MDM_ON","MDM_OFF","MDM_ON_IN_ANOTHER_MDM","READY_ZTD","MISSING_AGENT","ONLINE","OFFLINE","ENABLED","DISABLED","MISSING_BYPASS_CODE","MEETS_REQUIREMENTS","BELOW_MINIMUM_VERSION","UNSUPPORTED_OS_EDITION"]}},"ticketCreationStatus":{"description":"Statuses that also open a ticket, each one also listed in `nonCompliantStatus`. Omit it to keep the ticket statuses the rule already has (a status removed from `nonCompliantStatus` stops opening tickets either way); pass an empty array to open no ticket.","type":"array","items":{"type":"string","enum":["ACTIVE","NOT_PROTECTED","OFFLINE_7_DAYS","PENDING","PROTECTED","FAILED","NOT_ENCRYPTED","MISSING_RECOVERY_KEY","ENCRYPTED","ACTION_REQUIRED","GRACE_PERIOD","UP_TO_DATE","NOT_UP_TO_DATE","ENFORCED","ERROR","CREATION_PENDING","DEMOTION_PENDING","CREATED","CREATION_FAILED","SUCCESS","UNSUPPORTED","INSTALLED","MDM_ON","MDM_OFF","MDM_ON_IN_ANOTHER_MDM","READY_ZTD","MISSING_AGENT","ONLINE","OFFLINE","ENABLED","DISABLED","MISSING_BYPASS_CODE","MEETS_REQUIREMENTS","BELOW_MINIMUM_VERSION","UNSUPPORTED_OS_EDITION"]}}},"required":["type","nonCompliantStatus"]},"ComplianceAlertRuleResponse_Output":{"type":"object","properties":{"rule":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string","enum":["MDM_CONTROL_MALWAREBYTES","MDM_CONTROL_RECOVERY_OS","MDM_CONTROL_ENCRYPTION","MDM_CONTROL_OS_UPDATE","MDM_CONTROL_SOFTWARE_UPDATE","MDM_CONTROL_WIFI","MDM_CONTROL_ADMIN_USER_MANAGEMENT","MDM_CONTROL_ADMIN_USER_PASSWORD_ROTATION","MDM_CONTROL_DEVICE_NAMING","MDM_CONTROL_GOOGLE_CHROME","MDM_CONTROL_FIREWALL","MDM_CONTROL_USB_BLOCKING","MDM_CONTROL_ENTRA_SSO","MDM_CONTROL_OKTA_SSO","MDM_CONTROL_CUSTOM_FILE","MDM_CONTROL_PASSWORD_POLICY","MDM_CONTROL_SENTINEL_ONE","MDM_CONTROL_RUSTDESK","MDM_CONTROL_APP_BLOCKING","MDM_CONTROL_DISABLE_PROFILES_PANE","MDM_CONTROL_DISABLE_AIRDROP","MDM_CONTROL_SCREEN_CAPTURE","MDM_CONTROL_AIR_PRINT","MDM_CONTROL_PRIMO_SSO","MDM_CONTROL_WEB_CLIP","MDM_ENROLLMENT","MDM_ONLINE","MDM_ICLOUD_LOCK_STATUS","PRIMO_REQUIREMENT"]},"nonCompliantStatus":{"description":"Statuses that raise a compliance issue (\"Create Issue\" or \"Create Issue and Ticket\" in the cockpit).","type":"array","items":{"type":"string","enum":["ACTIVE","NOT_PROTECTED","OFFLINE_7_DAYS","PENDING","PROTECTED","FAILED","NOT_ENCRYPTED","MISSING_RECOVERY_KEY","ENCRYPTED","ACTION_REQUIRED","GRACE_PERIOD","UP_TO_DATE","NOT_UP_TO_DATE","ENFORCED","ERROR","CREATION_PENDING","DEMOTION_PENDING","CREATED","CREATION_FAILED","SUCCESS","UNSUPPORTED","INSTALLED","MDM_ON","MDM_OFF","MDM_ON_IN_ANOTHER_MDM","READY_ZTD","MISSING_AGENT","ONLINE","OFFLINE","ENABLED","DISABLED","MISSING_BYPASS_CODE","MEETS_REQUIREMENTS","BELOW_MINIMUM_VERSION","UNSUPPORTED_OS_EDITION"]}},"ticketCreationStatus":{"description":"Among `nonCompliantStatus`, the statuses that also open a ticket (\"Create Issue and Ticket\"). A status in neither list is \"Off\".","type":"array","items":{"type":"string","enum":["ACTIVE","NOT_PROTECTED","OFFLINE_7_DAYS","PENDING","PROTECTED","FAILED","NOT_ENCRYPTED","MISSING_RECOVERY_KEY","ENCRYPTED","ACTION_REQUIRED","GRACE_PERIOD","UP_TO_DATE","NOT_UP_TO_DATE","ENFORCED","ERROR","CREATION_PENDING","DEMOTION_PENDING","CREATED","CREATION_FAILED","SUCCESS","UNSUPPORTED","INSTALLED","MDM_ON","MDM_OFF","MDM_ON_IN_ANOTHER_MDM","READY_ZTD","MISSING_AGENT","ONLINE","OFFLINE","ENABLED","DISABLED","MISSING_BYPASS_CODE","MEETS_REQUIREMENTS","BELOW_MINIMUM_VERSION","UNSUPPORTED_OS_EDITION"]}},"config":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","type","nonCompliantStatus","ticketCreationStatus","config","createdAt","updatedAt"],"additionalProperties":false}},"required":["rule"],"additionalProperties":false},"UpdateComplianceAlertRuleBody":{"type":"object","properties":{"nonCompliantStatus":{"description":"Non-compliant device statuses that should trigger an alert for this rule. Only non-compliant statuses are accepted (compliant statuses like SUCCESS, ONLINE, ENCRYPTED, etc. are rejected). Pass an empty array to disable alerts.","type":"array","items":{"type":"string","enum":["ACTIVE","NOT_PROTECTED","OFFLINE_7_DAYS","PENDING","PROTECTED","FAILED","NOT_ENCRYPTED","MISSING_RECOVERY_KEY","ENCRYPTED","ACTION_REQUIRED","GRACE_PERIOD","UP_TO_DATE","NOT_UP_TO_DATE","ENFORCED","ERROR","CREATION_PENDING","DEMOTION_PENDING","CREATED","CREATION_FAILED","SUCCESS","UNSUPPORTED","INSTALLED","MDM_ON","MDM_OFF","MDM_ON_IN_ANOTHER_MDM","READY_ZTD","MISSING_AGENT","ONLINE","OFFLINE","ENABLED","DISABLED","MISSING_BYPASS_CODE","MEETS_REQUIREMENTS","BELOW_MINIMUM_VERSION","UNSUPPORTED_OS_EDITION"]}},"ticketCreationStatus":{"description":"Statuses that also open a ticket, each one also listed in `nonCompliantStatus`. Omit it to keep the ticket statuses the rule already has (a status removed from `nonCompliantStatus` stops opening tickets either way); pass an empty array to open no ticket.","type":"array","items":{"type":"string","enum":["ACTIVE","NOT_PROTECTED","OFFLINE_7_DAYS","PENDING","PROTECTED","FAILED","NOT_ENCRYPTED","MISSING_RECOVERY_KEY","ENCRYPTED","ACTION_REQUIRED","GRACE_PERIOD","UP_TO_DATE","NOT_UP_TO_DATE","ENFORCED","ERROR","CREATION_PENDING","DEMOTION_PENDING","CREATED","CREATION_FAILED","SUCCESS","UNSUPPORTED","INSTALLED","MDM_ON","MDM_OFF","MDM_ON_IN_ANOTHER_MDM","READY_ZTD","MISSING_AGENT","ONLINE","OFFLINE","ENABLED","DISABLED","MISSING_BYPASS_CODE","MEETS_REQUIREMENTS","BELOW_MINIMUM_VERSION","UNSUPPORTED_OS_EDITION"]}}},"required":["nonCompliantStatus"]},"GetTasks_Output":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"ticketId":{"description":"Id of the parent ticket","type":"string"},"reference":{"type":"string"},"title":{"type":"string"},"status":{"type":"string","enum":["PENDING","IN_PROGRESS","COMPLETED","CANCELLED","SCHEDULED","LOADING","SLEEPING"]},"priority":{"anyOf":[{"type":"string","enum":["LOW","MEDIUM","HIGH"]},{"type":"null"}]},"dueDate":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"scheduleDate":{"description":"Wake-up date of a SCHEDULED (dormant) task; null on any other status","anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"assignee":{"anyOf":[{"anyOf":[{"type":"object","properties":{"type":{"type":"string","const":"EMAIL"},"email":{"type":"string"},"displayName":{"type":"string"}},"required":["type","email","displayName"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"EMPLOYEE"},"employeeId":{"type":"string"},"displayName":{"type":"string"},"email":{"type":"string"},"pictureUrl":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["type","employeeId","displayName","email","pictureUrl"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"EXTERNAL_ADMIN"},"userId":{"type":"string"},"displayName":{"type":"string"},"email":{"type":"string"},"pictureUrl":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["type","userId","displayName","email","pictureUrl"],"additionalProperties":false}]},{"type":"null"}]},"isManuallyCompletable":{"description":"Whether a human (not only the system) may complete this task","type":"boolean"},"isAdminManaged":{"description":"Whether only an admin may assign this task or change its status","type":"boolean"},"tagIds":{"description":"Ids of the tags attached to this task","type":"array","items":{"type":"string"}},"aiAgentId":{"description":"Id of the AI agent handling it; null when no agent is on it","default":null,"anyOf":[{"type":"string"},{"type":"null"}]},"parentTicket":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"reference":{"type":"string"},"title":{"type":"string"}},"required":["id","reference","title"],"additionalProperties":false},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","ticketId","reference","title","status","priority","dueDate","scheduleDate","assignee","isManuallyCompletable","isAdminManaged","tagIds","aiAgentId","parentTicket","createdAt","updatedAt"],"additionalProperties":false}},"pagination":{"type":"object","properties":{"totalElements":{"type":"integer","minimum":0,"maximum":9007199254740991},"totalPages":{"type":"integer","minimum":0,"maximum":9007199254740991},"page":{"type":"integer","minimum":1,"maximum":9007199254740991},"perPage":{"type":"integer","minimum":1,"maximum":100}},"required":["totalElements","totalPages","page","perPage"],"additionalProperties":false}},"required":["data","pagination"],"additionalProperties":false},"CreateTaskBody":{"type":"object","properties":{"ticketId":{"description":"Id of the parent ticket: the 24-character `id` returned by getTickets or getTicket, not the reference displayed in the product (e.g. IT-1741).","type":"string","pattern":"^[a-f\\d]{24}$"},"title":{"type":"string","minLength":1},"description":{"description":"What the task expects: when it is done and what to do when it is blocked. Shown to whoever opens it.","type":"string","minLength":1},"assigneeEmployeeId":{"type":"string"},"priority":{"anyOf":[{"type":"string","enum":["LOW","MEDIUM","HIGH"]},{"type":"null"}]},"dueDate":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"tagIds":{"description":"Ids of the tags to attach to the task","type":"array","items":{"type":"string"}},"requester":{"description":"Open the task on behalf of an employee or email. Defaults to the API key / connected user.","anyOf":[{"type":"object","properties":{"type":{"type":"string","const":"EMPLOYEE"},"employeeId":{"type":"string","minLength":1}},"required":["type","employeeId"]},{"type":"object","properties":{"type":{"type":"string","const":"EMAIL"},"email":{"type":"string","minLength":1}},"required":["type","email"]}]}},"required":["ticketId","title"]},"TaskOutput_Output":{"type":"object","properties":{"id":{"type":"string"},"ticketId":{"type":"string"},"title":{"type":"string"},"status":{"type":"string","enum":["PENDING","IN_PROGRESS","COMPLETED","CANCELLED","SCHEDULED","LOADING","SLEEPING"]},"priority":{"anyOf":[{"type":"string","enum":["LOW","MEDIUM","HIGH"]},{"type":"null"}]},"dueDate":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"scheduleDate":{"description":"Wake-up date of a SCHEDULED (dormant) task; null on any other status","anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"wakeDate":{"description":"Pick-up date of a SLEEPING task, which nobody sees until then; null on any other status","anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"isManuallyCompletable":{"type":"boolean","description":"Whether a human (not only the system) may complete this task"},"isAdminManaged":{"type":"boolean","description":"Whether only an admin may assign this task or change its status"},"assignee":{"anyOf":[{"anyOf":[{"type":"object","properties":{"type":{"type":"string","const":"EMAIL"},"email":{"type":"string"}},"required":["type","email"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"EMPLOYEE"},"employeeId":{"type":"string"}},"required":["type","employeeId"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"EXTERNAL_ADMIN"},"userId":{"type":"string"}},"required":["type","userId"],"additionalProperties":false}]},{"type":"null"}]},"tagIds":{"type":"array","description":"Ids of the tags attached to this task","items":{"type":"string"}},"aiAgentId":{"description":"Id of the AI agent handling it; null when no agent is on it","default":null,"anyOf":[{"type":"string"},{"type":"null"}]},"type":{"description":"Type of a typed task, which Primo runs through its intent (EMPLOYEE_CREATION, EMAIL_ACCOUNT, SAAS_SELECTION, SAAS_PROVISIONING, EQUIPMENT_ORDER); null for a plain task","default":null,"anyOf":[{"type":"string"},{"type":"null"}]},"intentId":{"description":"Id of a typed task's intent, to pass to its update and execute tools; null for a plain task","default":null,"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["id","ticketId","title","status","priority","dueDate","scheduleDate","wakeDate","isManuallyCompletable","isAdminManaged","assignee","tagIds","aiAgentId","type","intentId"],"additionalProperties":false},"ScheduleTaskBody":{"type":"object","properties":{"ticketId":{"description":"Id of the parent ticket: the 24-character `id` returned by getTickets or getTicket, not the reference displayed in the product (e.g. IT-1741). Must be the ticket you are currently the agent of.","type":"string","pattern":"^[a-f\\d]{24}$"},"title":{"type":"string","minLength":1},"description":{"description":"What to do when this task wakes up. This is the only context you will have then — there is no separate prompt field, so write it as full instructions, not a one-line reminder.","type":"string","minLength":1},"wakeDate":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["ticketId","title","description","wakeDate"]},"UpdateTaskStatusBody":{"type":"object","properties":{"ticketId":{"description":"Id of the parent ticket: the 24-character `id` returned by getTickets or getTicket, not the reference displayed in the product (e.g. IT-1741).","type":"string","pattern":"^[a-f\\d]{24}$"},"status":{"type":"string","enum":["COMPLETED","CANCELLED"]}},"required":["ticketId","status"]},"UpdateTaskAssigneeBody":{"type":"object","properties":{"ticketId":{"description":"Id of the parent ticket: the 24-character `id` returned by getTickets or getTicket, not the reference displayed in the product (e.g. IT-1741).","type":"string","pattern":"^[a-f\\d]{24}$"},"assigneeEmployeeId":{"type":"string","minLength":1}},"required":["ticketId","assigneeEmployeeId"]},"GetTickets_Output":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"reference":{"type":"string"},"title":{"type":"string"},"status":{"type":"string","enum":["PENDING","IN_PROGRESS","COMPLETED","CANCELLED","SCHEDULED","LOADING","SLEEPING"]},"priority":{"anyOf":[{"type":"string","enum":["LOW","MEDIUM","HIGH"]},{"type":"null"}]},"assignee":{"anyOf":[{"anyOf":[{"type":"object","properties":{"type":{"type":"string","const":"EMAIL"},"email":{"type":"string"}},"required":["type","email"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"EMPLOYEE"},"employeeId":{"type":"string"}},"required":["type","employeeId"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"EXTERNAL_ADMIN"},"userId":{"type":"string"}},"required":["type","userId"],"additionalProperties":false}]},{"type":"null"}]},"requester":{"description":"Who the ticket was opened on behalf of (its creator)","anyOf":[{"type":"object","properties":{"type":{"type":"string","const":"EMPLOYEE"},"employeeId":{"type":"string"}},"required":["type","employeeId"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"EXTERNAL_ADMIN"},"userId":{"type":"string"}},"required":["type","userId"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"EMAIL"},"email":{"type":"string"}},"required":["type","email"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"PRIMO"}},"required":["type"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"API"}},"required":["type"],"additionalProperties":false},{"description":"The autonomous AI agent","type":"object","properties":{"type":{"type":"string","const":"AGENT"},"agentId":{"description":"Id of the AI agent behind the action","anyOf":[{"type":"string"},{"type":"null"}]}},"required":["type"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"SLACK_USER"},"name":{"type":"string"}},"required":["type","name"],"additionalProperties":false}]},"dueDate":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"wakeDate":{"description":"Wake-up date of a SLEEPING ticket, which nobody sees until then; null on any other status","default":null,"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"tagIds":{"description":"Ids of the tags attached to this ticket","type":"array","items":{"type":"string"}},"aiAgentId":{"description":"Id of the AI agent handling it; null when no agent is on it","default":null,"anyOf":[{"type":"string"},{"type":"null"}]},"tasks":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"ticketId":{"type":"string"},"title":{"type":"string"},"status":{"type":"string","enum":["PENDING","IN_PROGRESS","COMPLETED","CANCELLED","SCHEDULED","LOADING","SLEEPING"]},"priority":{"anyOf":[{"type":"string","enum":["LOW","MEDIUM","HIGH"]},{"type":"null"}]},"dueDate":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"scheduleDate":{"description":"Wake-up date of a SCHEDULED (dormant) task; null on any other status","anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"wakeDate":{"description":"Pick-up date of a SLEEPING task, which nobody sees until then; null on any other status","anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"isManuallyCompletable":{"description":"Whether a human (not only the system) may complete this task","type":"boolean"},"isAdminManaged":{"description":"Whether only an admin may assign this task or change its status","type":"boolean"},"assignee":{"anyOf":[{"anyOf":[{"type":"object","properties":{"type":{"type":"string","const":"EMAIL"},"email":{"type":"string"}},"required":["type","email"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"EMPLOYEE"},"employeeId":{"type":"string"}},"required":["type","employeeId"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"EXTERNAL_ADMIN"},"userId":{"type":"string"}},"required":["type","userId"],"additionalProperties":false}]},{"type":"null"}]},"tagIds":{"description":"Ids of the tags attached to this task","type":"array","items":{"type":"string"}},"aiAgentId":{"description":"Id of the AI agent handling it; null when no agent is on it","default":null,"anyOf":[{"type":"string"},{"type":"null"}]},"type":{"description":"Type of a typed task, which Primo runs through its intent (EMPLOYEE_CREATION, EMAIL_ACCOUNT, SAAS_SELECTION, SAAS_PROVISIONING, EQUIPMENT_ORDER); null for a plain task","default":null,"anyOf":[{"type":"string"},{"type":"null"}]},"intentId":{"description":"Id of a typed task's intent, to pass to its update and execute tools; null for a plain task","default":null,"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["id","ticketId","title","status","priority","dueDate","scheduleDate","wakeDate","isManuallyCompletable","isAdminManaged","assignee","tagIds","aiAgentId","type","intentId"],"additionalProperties":false}}},"required":["id","reference","title","status","priority","assignee","requester","dueDate","wakeDate","createdAt","updatedAt","tagIds","aiAgentId","tasks"],"additionalProperties":false}},"pagination":{"type":"object","properties":{"totalElements":{"type":"integer","minimum":0,"maximum":9007199254740991},"totalPages":{"type":"integer","minimum":0,"maximum":9007199254740991},"page":{"type":"integer","minimum":1,"maximum":9007199254740991},"perPage":{"type":"integer","minimum":1,"maximum":100}},"required":["totalElements","totalPages","page","perPage"],"additionalProperties":false}},"required":["data","pagination"],"additionalProperties":false},"CountTicketsBody":{"type":"object","properties":{"queries":{"description":"Up to 20 ticket queries, each under a label you choose (letters, digits, \"_\" or \"-\"), e.g. `{\"pending\":{\"status\":\"PENDING\"},\"pendingHigh\":{\"status\":\"PENDING\",\"priority\":\"HIGH\"}}`. A query takes the `status`, `priority`, `searchTerm`, `assigneeEmployeeId` and `tagIds` of `getTickets`, nothing else.","type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"object","properties":{"status":{"type":"string","enum":["PENDING","IN_PROGRESS","COMPLETED","CANCELLED","SCHEDULED","LOADING"]},"priority":{"type":"string","enum":["LOW","MEDIUM","HIGH"]},"searchTerm":{"description":"Case-insensitive substring of the title or description, or a ticket reference (`IT-1741` or `1741`).","type":"string","minLength":1},"assigneeEmployeeId":{"type":"string"},"tagIds":{"description":"Filter tickets by tag ids","type":"array","items":{"type":"string"}}},"additionalProperties":false}}},"required":["queries"]},"CountTickets_Output":{"type":"object","properties":{"counts":{"type":"object","description":"The number of records matching each query, under the label the query was sent with","propertyNames":{"type":"string"},"additionalProperties":{"type":"integer","minimum":0,"maximum":9007199254740991}}},"required":["counts"],"additionalProperties":false},"TicketOutput_Output":{"type":"object","properties":{"id":{"type":"string"},"reference":{"type":"string"},"title":{"type":"string"},"status":{"type":"string","enum":["PENDING","IN_PROGRESS","COMPLETED","CANCELLED","SCHEDULED","LOADING","SLEEPING"]},"priority":{"anyOf":[{"type":"string","enum":["LOW","MEDIUM","HIGH"]},{"type":"null"}]},"assignee":{"anyOf":[{"anyOf":[{"type":"object","properties":{"type":{"type":"string","const":"EMAIL"},"email":{"type":"string"}},"required":["type","email"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"EMPLOYEE"},"employeeId":{"type":"string"}},"required":["type","employeeId"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"EXTERNAL_ADMIN"},"userId":{"type":"string"}},"required":["type","userId"],"additionalProperties":false}]},{"type":"null"}]},"requester":{"description":"Who the ticket was opened on behalf of (its creator)","anyOf":[{"type":"object","properties":{"type":{"type":"string","const":"EMPLOYEE"},"employeeId":{"type":"string"}},"required":["type","employeeId"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"EXTERNAL_ADMIN"},"userId":{"type":"string"}},"required":["type","userId"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"EMAIL"},"email":{"type":"string"}},"required":["type","email"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"PRIMO"}},"required":["type"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"API"}},"required":["type"],"additionalProperties":false},{"description":"The autonomous AI agent","type":"object","properties":{"type":{"type":"string","const":"AGENT"},"agentId":{"description":"Id of the AI agent behind the action","anyOf":[{"type":"string"},{"type":"null"}]}},"required":["type"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"SLACK_USER"},"name":{"type":"string"}},"required":["type","name"],"additionalProperties":false}]},"dueDate":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"wakeDate":{"description":"Wake-up date of a SLEEPING ticket, which nobody sees until then; null on any other status","default":null,"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"tagIds":{"type":"array","description":"Ids of the tags attached to this ticket","items":{"type":"string"}},"aiAgentId":{"description":"Id of the AI agent handling it; null when no agent is on it","default":null,"anyOf":[{"type":"string"},{"type":"null"}]},"tasks":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"ticketId":{"type":"string"},"title":{"type":"string"},"status":{"type":"string","enum":["PENDING","IN_PROGRESS","COMPLETED","CANCELLED","SCHEDULED","LOADING","SLEEPING"]},"priority":{"anyOf":[{"type":"string","enum":["LOW","MEDIUM","HIGH"]},{"type":"null"}]},"dueDate":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"scheduleDate":{"description":"Wake-up date of a SCHEDULED (dormant) task; null on any other status","anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"wakeDate":{"description":"Pick-up date of a SLEEPING task, which nobody sees until then; null on any other status","anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"isManuallyCompletable":{"description":"Whether a human (not only the system) may complete this task","type":"boolean"},"isAdminManaged":{"description":"Whether only an admin may assign this task or change its status","type":"boolean"},"assignee":{"anyOf":[{"anyOf":[{"type":"object","properties":{"type":{"type":"string","const":"EMAIL"},"email":{"type":"string"}},"required":["type","email"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"EMPLOYEE"},"employeeId":{"type":"string"}},"required":["type","employeeId"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"EXTERNAL_ADMIN"},"userId":{"type":"string"}},"required":["type","userId"],"additionalProperties":false}]},{"type":"null"}]},"tagIds":{"description":"Ids of the tags attached to this task","type":"array","items":{"type":"string"}},"aiAgentId":{"description":"Id of the AI agent handling it; null when no agent is on it","default":null,"anyOf":[{"type":"string"},{"type":"null"}]},"type":{"description":"Type of a typed task, which Primo runs through its intent (EMPLOYEE_CREATION, EMAIL_ACCOUNT, SAAS_SELECTION, SAAS_PROVISIONING, EQUIPMENT_ORDER); null for a plain task","default":null,"anyOf":[{"type":"string"},{"type":"null"}]},"intentId":{"description":"Id of a typed task's intent, to pass to its update and execute tools; null for a plain task","default":null,"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["id","ticketId","title","status","priority","dueDate","scheduleDate","wakeDate","isManuallyCompletable","isAdminManaged","assignee","tagIds","aiAgentId","type","intentId"],"additionalProperties":false}},"comments":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"text":{"type":"string"},"creator":{"anyOf":[{"type":"object","properties":{"type":{"type":"string","const":"EMPLOYEE"},"employeeId":{"type":"string"}},"required":["type","employeeId"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"EXTERNAL_ADMIN"},"userId":{"type":"string"}},"required":["type","userId"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"EMAIL"},"email":{"type":"string"}},"required":["type","email"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"PRIMO"}},"required":["type"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"API"}},"required":["type"],"additionalProperties":false},{"description":"The autonomous AI agent","type":"object","properties":{"type":{"type":"string","const":"AGENT"},"agentId":{"description":"Id of the AI agent behind the action","anyOf":[{"type":"string"},{"type":"null"}]}},"required":["type"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"SLACK_USER"},"name":{"type":"string"}},"required":["type","name"],"additionalProperties":false}]},"visibility":{"description":"INTERNAL comments are team-only (admins and assignee), never shown to the requester; PUBLIC comments are visible to the ticket requester","type":"string","enum":["INTERNAL","PUBLIC"]},"taskId":{"description":"Id of the ticket task this comment concerns, if any","anyOf":[{"type":"string"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","text","creator","visibility","taskId","createdAt"],"additionalProperties":false}},"relatedObjects":{"type":"array","items":{"type":"object","properties":{"linkId":{"description":"Id of the link itself — use it to unlink the related object","type":"string"},"relatedType":{"type":"string","enum":["DEVICE","EMPLOYEE","IDENTITY","ORDER","SHIPMENT","COMPANY_SAAS_APPLICATION"]},"relatedId":{"description":"Id of the related resource (device, employee, SaaS identity, order, shipment or company SaaS application)","type":"string"},"resolved":{"description":"False when the related resource no longer exists","type":"boolean"}},"required":["linkId","relatedType","relatedId","resolved"],"additionalProperties":false}}},"required":["id","reference","title","status","priority","assignee","requester","dueDate","wakeDate","createdAt","updatedAt","tagIds","aiAgentId","tasks","comments","relatedObjects"],"additionalProperties":false},"CreateTicketBody":{"type":"object","properties":{"title":{"type":"string","minLength":1},"assigneeEmployeeId":{"type":"string"},"priority":{"default":null,"anyOf":[{"type":"string","enum":["LOW","MEDIUM","HIGH"]},{"type":"null"}]},"dueDate":{"default":null,"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"tagIds":{"description":"Ids of the tags to attach to the ticket","type":"array","items":{"type":"string"}},"requester":{"description":"Open the ticket on behalf of an employee or email. Defaults to the API key / connected user.","anyOf":[{"type":"object","properties":{"type":{"type":"string","const":"EMPLOYEE"},"employeeId":{"type":"string","minLength":1}},"required":["type","employeeId"]},{"type":"object","properties":{"type":{"type":"string","const":"EMAIL"},"email":{"type":"string","minLength":1}},"required":["type","email"]}]},"wakeDate":{"description":"Create the ticket asleep until this date/time (ISO 8601): nobody sees it until then, and it wakes as an ordinary pending ticket. System agent only. Must be in the future and within 365 days from now.","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["title"]},"UpdateTicketBody":{"type":"object","properties":{"title":{"type":"string","minLength":1},"description":{"anyOf":[{"type":"string"},{"type":"null"}]},"priority":{"anyOf":[{"type":"string","enum":["LOW","MEDIUM","HIGH"]},{"type":"null"}]},"dueDate":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"assigneeEmployeeId":{"type":"string","minLength":1},"tagIds":{"type":"array","items":{"type":"string"}}},"description":"Partial update — only the provided fields are changed. Use updateTicketStatus to change status."},"UpdateTicketStatusBody":{"type":"object","properties":{"status":{"type":"string","enum":["PENDING","IN_PROGRESS","COMPLETED","CANCELLED"]}},"required":["status"]},"UpdateTicketAssigneeBody":{"type":"object","properties":{"assigneeEmployeeId":{"type":"string","minLength":1}},"required":["assigneeEmployeeId"]},"UpdateTicketAiAgentBody":{"type":"object","properties":{"aiAgentId":{"description":"Id of the AI agent to put on the ticket. Pass null to take the agent currently on it off.","anyOf":[{"type":"string","minLength":1},{"type":"null"}]}},"required":["aiAgentId"]},"UpdateTicketPriorityBody":{"type":"object","properties":{"priority":{"anyOf":[{"type":"string","enum":["LOW","MEDIUM","HIGH"]},{"type":"null"}]}},"required":["priority"]},"CreateTicketCommentBody":{"type":"object","properties":{"text":{"description":"Comment text. Mention a person with @[Display Name](employee:<employeeId>) or @[Display Name](external_admin:<clerkUserId>); mentioned people are notified","type":"string","minLength":1},"visibility":{"default":"INTERNAL","description":"INTERNAL comments are team-only (admins and assignee), never shown to the requester; PUBLIC comments are visible to the ticket requester","type":"string","enum":["INTERNAL","PUBLIC"]},"taskId":{"description":"Id of a task of this ticket the comment concerns","type":"string"},"fileIds":{"description":"Ids of files to attach to the comment, as returned when the file was uploaded","type":"array","items":{"type":"string"}}},"required":["text"]},"TicketCommentOutput_Output":{"type":"object","properties":{"id":{"type":"string"},"text":{"type":"string"},"creator":{"anyOf":[{"type":"object","properties":{"type":{"type":"string","const":"EMPLOYEE"},"employeeId":{"type":"string"}},"required":["type","employeeId"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"EXTERNAL_ADMIN"},"userId":{"type":"string"}},"required":["type","userId"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"EMAIL"},"email":{"type":"string"}},"required":["type","email"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"PRIMO"}},"required":["type"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"API"}},"required":["type"],"additionalProperties":false},{"description":"The autonomous AI agent","type":"object","properties":{"type":{"type":"string","const":"AGENT"},"agentId":{"description":"Id of the AI agent behind the action","anyOf":[{"type":"string"},{"type":"null"}]}},"required":["type"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"SLACK_USER"},"name":{"type":"string"}},"required":["type","name"],"additionalProperties":false}]},"visibility":{"type":"string","description":"INTERNAL comments are team-only (admins and assignee), never shown to the requester; PUBLIC comments are visible to the ticket requester","enum":["INTERNAL","PUBLIC"]},"taskId":{"description":"Id of the ticket task this comment concerns, if any","anyOf":[{"type":"string"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","text","creator","visibility","taskId","createdAt"],"additionalProperties":false},"LinkTicketRelatedObjectBody":{"type":"object","properties":{"relatedType":{"type":"string","enum":["DEVICE","EMPLOYEE","IDENTITY","ORDER","SHIPMENT","COMPANY_SAAS_APPLICATION"]},"relatedId":{"description":"Id of the device, employee, SaaS identity, order, shipment or company SaaS application to link","type":"string","minLength":1}},"required":["relatedType","relatedId"]},"LinkedTicketRelatedObject_Output":{"type":"object","properties":{"linkId":{"type":"string"},"relatedType":{"type":"string","enum":["DEVICE","EMPLOYEE","IDENTITY","ORDER","SHIPMENT","COMPANY_SAAS_APPLICATION"]},"relatedId":{"type":"string"}},"required":["linkId","relatedType","relatedId"],"additionalProperties":false},"UnlinkTicketRelatedObjectResult_Output":{"type":"object","properties":{"deleted":{"type":"boolean"}},"required":["deleted"],"additionalProperties":false},"AddTicketSubscribersBody":{"type":"object","properties":{"subscribers":{"minItems":1,"type":"array","items":{"anyOf":[{"type":"object","properties":{"type":{"type":"string","const":"EMPLOYEE"},"employeeId":{"type":"string"}},"required":["type","employeeId"]},{"type":"object","properties":{"type":{"type":"string","const":"EXTERNAL_ADMIN"},"userId":{"type":"string"}},"required":["type","userId"]}]}}},"required":["subscribers"]},"TicketSubscribersOutput_Output":{"type":"object","properties":{"subscribers":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"type":{"type":"string","const":"EMPLOYEE"},"employeeId":{"type":"string"}},"required":["type","employeeId"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"EXTERNAL_ADMIN"},"userId":{"type":"string"}},"required":["type","userId"],"additionalProperties":false}]}}},"required":["subscribers"],"additionalProperties":false},"RemoveTicketSubscriberBody":{"type":"object","properties":{"subscriber":{"anyOf":[{"type":"object","properties":{"type":{"type":"string","const":"EMPLOYEE"},"employeeId":{"type":"string"}},"required":["type","employeeId"]},{"type":"object","properties":{"type":{"type":"string","const":"EXTERNAL_ADMIN"},"userId":{"type":"string"}},"required":["type","userId"]}]}},"required":["subscriber"]},"ListTicketSubscribersOutput_Output":{"type":"object","properties":{"subscribers":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"type":{"type":"string","const":"EMAIL"},"email":{"type":"string"},"displayName":{"type":"string"}},"required":["type","email","displayName"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"EMPLOYEE"},"employeeId":{"type":"string"},"displayName":{"type":"string"},"email":{"type":"string"},"pictureUrl":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["type","employeeId","displayName","email","pictureUrl"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"EXTERNAL_ADMIN"},"userId":{"type":"string"},"displayName":{"type":"string"},"email":{"type":"string"},"pictureUrl":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["type","userId","displayName","email","pictureUrl"],"additionalProperties":false}]}}},"required":["subscribers"],"additionalProperties":false},"ListTicketTagsOutput_Output":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","name","createdAt","updatedAt"],"additionalProperties":false}}},"required":["data"],"additionalProperties":false},"CreateTicketTagBody":{"type":"object","properties":{"name":{"type":"string","minLength":1}},"required":["name"]},"TicketTagOutput_Output":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","name","createdAt","updatedAt"],"additionalProperties":false},"UpdateTicketTagBody":{"type":"object","properties":{"name":{"type":"string","minLength":1}},"required":["name"]},"DeleteTicketTagResult_Output":{"type":"object","properties":{"deleted":{"type":"boolean"}},"required":["deleted"],"additionalProperties":false},"GetSoftwares_Output":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"platform":{"type":"string","enum":["macos","windows","ios","ipados","android","linux","chromeos","unknown"]},"source":{"type":"string","enum":["fma","appStore","customPackage","androidStore"]},"installationType":{"type":"string","enum":["manual","automatic"]},"autoUpdatePackage":{"description":"iOS and iPadOS App Store apps only: the App Store updates the app on devices. Ignored for every other source: Fleet keeps a Fleet-maintained app on its latest version itself unless getSoftware shows a pinnedVersion, and a custom package has no update mechanism","type":"boolean"},"autoInstallUpdate":{"description":"Fleet-maintained apps only: devices that run an older version get the installer version, inside patchWindow. Ignored for App Store apps (see autoUpdatePackage) and custom packages","type":"boolean"},"targetMethod":{"type":"string","enum":["All","DeviceGroup"]}},"required":["id","name","platform","source","installationType","autoUpdatePackage","autoInstallUpdate","targetMethod"],"additionalProperties":false}},"pagination":{"type":"object","properties":{"totalElements":{"type":"integer","minimum":0,"maximum":9007199254740991},"totalPages":{"type":"integer","minimum":0,"maximum":9007199254740991},"page":{"type":"integer","minimum":1,"maximum":9007199254740991},"perPage":{"type":"integer","minimum":1,"maximum":100}},"required":["totalElements","totalPages","page","perPage"],"additionalProperties":false}},"required":["data","pagination"],"additionalProperties":false},"GetVulnerabilities_Output":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"cve":{"type":"string"},"createdAt":{"type":"string"},"hostsCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"hostsCountUpdatedAt":{"type":"string"},"detailsLink":{"type":"string"},"cvssScore":{"anyOf":[{"type":"number"},{"type":"null"}]},"epssProbability":{"anyOf":[{"type":"number"},{"type":"null"}]},"cisaKnownExploit":{"anyOf":[{"type":"boolean"},{"type":"null"}]},"cvePublished":{"anyOf":[{"type":"string"},{"type":"null"}]},"cveDescription":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["cve","createdAt","hostsCount","hostsCountUpdatedAt","detailsLink","cvssScore","epssProbability","cisaKnownExploit","cvePublished","cveDescription"],"additionalProperties":false}},"pagination":{"type":"object","properties":{"page":{"type":"integer","minimum":1,"maximum":9007199254740991},"perPage":{"type":"integer","minimum":1,"maximum":100},"hasNextPage":{"type":"boolean"},"hasPreviousPage":{"type":"boolean"},"totalElements":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]}},"required":["page","perPage","hasNextPage","hasPreviousPage","totalElements"],"additionalProperties":false}},"required":["data","pagination"],"additionalProperties":false},"GetVulnerability_Output":{"type":"object","properties":{"cve":{"type":"string"},"createdAt":{"type":"string"},"hostsCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"hostsCountUpdatedAt":{"type":"string"},"detailsLink":{"type":"string"},"cvssScore":{"anyOf":[{"type":"number"},{"type":"null"}]},"epssProbability":{"anyOf":[{"type":"number"},{"type":"null"}]},"cisaKnownExploit":{"anyOf":[{"type":"boolean"},{"type":"null"}]},"cvePublished":{"anyOf":[{"type":"string"},{"type":"null"}]},"cveDescription":{"anyOf":[{"type":"string"},{"type":"null"}]},"osVersions":{"type":"array","items":{"type":"object","properties":{"osVersionId":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"hostsCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"name":{"type":"string"},"nameOnly":{"type":"string"},"version":{"type":"string"},"resolvedInVersion":{"anyOf":[{"type":"string"},{"type":"null"}]},"generatedCpes":{"type":"array","items":{"type":"string"}}},"required":["osVersionId","hostsCount","name","nameOnly","version","resolvedInVersion","generatedCpes"],"additionalProperties":false}},"software":{"type":"array","items":{"type":"object","properties":{"id":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"softwareTitleId":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"name":{"type":"string"},"version":{"type":"string"},"source":{"type":"string"},"generatedCpe":{"anyOf":[{"type":"string"},{"type":"null"}]},"hostsCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"resolvedInVersion":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["id","softwareTitleId","name","version","source","generatedCpe","hostsCount","resolvedInVersion"],"additionalProperties":false}}},"required":["cve","createdAt","hostsCount","hostsCountUpdatedAt","detailsLink","cvssScore","epssProbability","cisaKnownExploit","cvePublished","cveDescription","osVersions","software"],"additionalProperties":false},"GetSoftwareDevices_Output":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"deviceId":{"type":"string"},"deviceName":{"anyOf":[{"type":"string"},{"type":"null"}]},"platform":{"type":"string","enum":["macos","windows","ios","ipados","android","linux","chromeos","unknown"]},"status":{"type":"string","enum":["installed","failed","in_progress","not_installed"]},"installedVersion":{"anyOf":[{"type":"string"},{"type":"null"}]},"fleetDeepLink":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["deviceId","deviceName","platform","status","installedVersion","fleetDeepLink"],"additionalProperties":false}},"pagination":{"type":"object","properties":{"totalElements":{"type":"integer","minimum":0,"maximum":9007199254740991},"totalPages":{"type":"integer","minimum":0,"maximum":9007199254740991},"page":{"type":"integer","minimum":1,"maximum":9007199254740991},"perPage":{"type":"integer","minimum":1,"maximum":100}},"required":["totalElements","totalPages","page","perPage"],"additionalProperties":false}},"required":["data","pagination"],"additionalProperties":false},"DeleteSoftwareResult_Output":{"type":"object","properties":{"success":{"type":"boolean","const":true},"message":{"type":"string","description":"A human-readable description of the action"}},"required":["success","message"],"additionalProperties":false},"SyncCompanySoftwaresResult_Output":{"type":"object","properties":{"success":{"type":"boolean"},"message":{"type":"string","description":"A human-readable description of the sync"}},"required":["success","message"],"additionalProperties":false},"SimulateSoftwareTargetCount_Output":{"type":"object","properties":{"count":{"type":"integer","description":"Number of devices matching the targeting criteria","minimum":0,"maximum":9007199254740991}},"required":["count"],"additionalProperties":false},"ResolveSoftwareTargetCounts_Output":{"type":"object","properties":{"counts":{"type":"object","propertyNames":{"description":"Software ID","type":"string"},"additionalProperties":{"description":"Target device count","type":"integer","minimum":0,"maximum":9007199254740991}}},"required":["counts"],"additionalProperties":false},"GetSoftwareDeviceCounts_Output":{"type":"object","properties":{"counts":{"type":"object","propertyNames":{"description":"Software ID","type":"string"},"additionalProperties":{"type":"object","properties":{"installed":{"type":"integer","minimum":0,"maximum":9007199254740991},"inProgress":{"type":"integer","minimum":0,"maximum":9007199254740991},"failed":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["installed","inProgress","failed"],"additionalProperties":false}}},"required":["counts"],"additionalProperties":false},"GetBillingProfiles_Output":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"currency":{"anyOf":[{"type":"string","enum":["EUR","GBP","USD","CHF","CAD"]},{"type":"null"}]},"countryCode":{"anyOf":[{"type":"string"},{"type":"null"}]},"eligibleForDeploy":{"description":"Whether this profile can be used to place a deploy order","type":"boolean"}},"required":["id","name","eligibleForDeploy"],"additionalProperties":false}}},"required":["data"],"additionalProperties":false},"GetAiUsage_Output":{"type":"object","properties":{"from":{"type":"string","description":"Start of the period the figures cover, inclusive","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"to":{"type":"string","description":"End of the period the figures cover, exclusive","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"totalCredits":{"type":"number","description":"Credits spent across every feature over the period"},"totalRunCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"byFeature":{"type":"array","description":"Highest spending feature first","items":{"type":"object","properties":{"feature":{"description":"The product surface the credits were spent on","type":"string","enum":["chat","custom_agent","trigger","tickets","it_support","onboarding","offboarding","equipment_policy","purchasing_policy","custom_fields_auto_fill","compliance","ai_dashboard"]},"runCount":{"description":"Number of metered generations recorded for this feature","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"credits":{"description":"Credits spent by this feature over the period","type":"number"},"sharePercent":{"description":"Share of the period total credits, in percent, rounded","type":"number"},"inputTokens":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"outputTokens":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"totalTokens":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["feature","runCount","credits","sharePercent","inputTokens","outputTokens","totalTokens"],"additionalProperties":false}},"byDay":{"type":"array","description":"One entry per day that recorded usage, chronological","items":{"type":"object","properties":{"day":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},"credits":{"type":"number"},"runCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["day","credits","runCount"],"additionalProperties":false}}},"required":["from","to","totalCredits","totalRunCount","byFeature","byDay"],"additionalProperties":false},"GetOrders_Output":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"reference":{"type":"string"},"status":{"type":"string","enum":["PLACED","CONFIRMED","SHIPPED","CLOSED","CANCELED"]},"employeeId":{"anyOf":[{"type":"string"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"onboardingDate":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"priceNoVAT":{"description":"Price excluding VAT, in the order currency","type":"number"},"currency":{"anyOf":[{"type":"string","enum":["EUR","GBP","USD","CHF","CAD"]},{"type":"null"}]},"cancelRequest":{"type":"boolean"},"products":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"type":{"type":"string","enum":["LAPTOP","SMARTPHONE","TABLET","MONITOR","KEYBOARD","MOUSE","MOUSEPAD","WEBCAM","HEADSET","SPEAKER","CABLE_ADAPTER","HUB","CHARGER","STORAGE_DEVICE","LAPTOP_CASE","SHIPPING_MATERIAL","ERGONOMIC","WARRANTY","OTHER"]},"supplierName":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["id","name","type"],"additionalProperties":false}},"purchases":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string","enum":["PENDING","FULFILLED","SHIPPED","DELIVERED","UNKNOWN","PRE_TRANSIT","IN_TRANSIT","OUT_FOR_DELIVERY","AVAILABLE_FOR_PICKUP","RETURN_TO_SENDER","FAILURE","CANCELLED","ERROR"]},"products":{"type":"array","items":{"type":"string"}},"trackingLink":{"anyOf":[{"type":"string"},{"type":"null"}]},"estimatedDeliveryDate":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]}},"required":["id","status","products"],"additionalProperties":false}}},"required":["id","reference","status","createdAt","priceNoVAT","cancelRequest","products","purchases"],"additionalProperties":false}},"pagination":{"type":"object","properties":{"totalElements":{"type":"integer","minimum":0,"maximum":9007199254740991},"totalPages":{"type":"integer","minimum":0,"maximum":9007199254740991},"page":{"type":"integer","minimum":1,"maximum":9007199254740991},"perPage":{"type":"integer","minimum":1,"maximum":100}},"required":["totalElements","totalPages","page","perPage"],"additionalProperties":false}},"required":["data","pagination"],"additionalProperties":false},"GetOrder_Output":{"type":"object","properties":{"id":{"type":"string"},"reference":{"type":"string"},"status":{"type":"string","enum":["PLACED","CONFIRMED","SHIPPED","CLOSED","CANCELED"]},"employeeId":{"anyOf":[{"type":"string"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"onboardingDate":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"priceNoVAT":{"type":"number","description":"Price excluding VAT, in the order currency"},"currency":{"anyOf":[{"type":"string","enum":["EUR","GBP","USD","CHF","CAD"]},{"type":"null"}]},"cancelRequest":{"type":"boolean"},"products":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"type":{"type":"string","enum":["LAPTOP","SMARTPHONE","TABLET","MONITOR","KEYBOARD","MOUSE","MOUSEPAD","WEBCAM","HEADSET","SPEAKER","CABLE_ADAPTER","HUB","CHARGER","STORAGE_DEVICE","LAPTOP_CASE","SHIPPING_MATERIAL","ERGONOMIC","WARRANTY","OTHER"]},"supplierName":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["id","name","type"],"additionalProperties":false}},"purchases":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string","enum":["PENDING","FULFILLED","SHIPPED","DELIVERED","UNKNOWN","PRE_TRANSIT","IN_TRANSIT","OUT_FOR_DELIVERY","AVAILABLE_FOR_PICKUP","RETURN_TO_SENDER","FAILURE","CANCELLED","ERROR"]},"products":{"type":"array","items":{"type":"string"}},"trackingLink":{"anyOf":[{"type":"string"},{"type":"null"}]},"estimatedDeliveryDate":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]}},"required":["id","status","products"],"additionalProperties":false}}},"required":["id","reference","status","createdAt","priceNoVAT","cancelRequest","products","purchases"],"additionalProperties":false},"CreateOrderBody":{"type":"object","properties":{"initiatorEmail":{"description":"Email of the order initiator (defaults to the first company admin)","anyOf":[{"type":"string"},{"type":"null"}]},"countryCode":{"description":"Catalog country code (lowercase ISO 3166-1 alpha-2)","type":"string"},"data":{"type":"object","properties":{"employeeId":{"description":"Employee the order is for (null for a stock order)","anyOf":[{"type":"string"},{"type":"null"}]},"status":{"description":"Must be PLACED","type":"string","enum":["PLACED","CONFIRMED","SHIPPED","CLOSED","CANCELED"]},"shippingAddressType":{"anyOf":[{"type":"string","enum":["OFFICE","HOME","NEW"]},{"type":"null"}]},"shippingAddress":{"type":"object","properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}]},"contactName":{"anyOf":[{"type":"string"},{"type":"null"}]},"phone":{"anyOf":[{"type":"string"},{"type":"null"}]},"street":{"type":"string","minLength":1},"complement":{"anyOf":[{"type":"string"},{"type":"null"}]},"postalCode":{"type":"string","minLength":1},"city":{"type":"string","minLength":1},"country":{"anyOf":[{"type":"string"},{"type":"null"}]},"countryCode":{"anyOf":[{"type":"string"},{"type":"null"}]},"type":{"anyOf":[{"type":"string","enum":["HOME","WORK"]},{"type":"null"}]}},"required":["phone","street","postalCode","city"]},"billingProfileId":{"description":"Required: an eligible company billing profile id","type":"string","minLength":1},"notificationEmails":{"type":"array","items":{"type":"string"}},"internalComment":{"anyOf":[{"type":"string"},{"type":"null"}]},"companyComment":{"anyOf":[{"type":"string"},{"type":"null"}]},"appleCareEnterprise":{"anyOf":[{"type":"string"},{"type":"null"}]},"companyPurchaseNumber":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["status","shippingAddress","billingProfileId"]},"products":{"type":"array","items":{"type":"object","properties":{"id":{"description":"Catalog product id","type":"string"},"variantId":{"description":"Selected product variant id","type":"string"},"supplierId":{"description":"Supplier id for this product","type":"string"},"hasZTD":{"type":"boolean"},"configuration":{"type":"object","properties":{"enableZTD":{"type":"boolean"},"enableACE":{"type":"boolean"}},"required":["enableZTD","enableACE"]}},"required":["id","variantId","supplierId","configuration"]}},"enableInvitationReminder":{"type":"object","properties":{"enabled":{"type":"boolean"}},"required":["enabled"]}},"required":["data"]},"CreatedOrder_Output":{"type":"object","properties":{"id":{"type":"string"},"reference":{"type":"string"},"status":{"type":"string","enum":["PLACED","CONFIRMED","SHIPPED","CLOSED","CANCELED"]}},"required":["id","reference","status"],"additionalProperties":false},"GetOrderCustomFields_Output":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"field":{"type":"object","properties":{"id":{"description":"CustomField id (MongoDB ObjectId string).","type":"string"},"label":{"type":"string"},"fieldType":{"description":"Type of data this field holds.","type":"string","enum":["SELECT","MULTI_SELECT","CHECKBOX","TEXT","DATE","NUMBER","URL","IMAGE"]},"applyTo":{"type":"array","items":{"type":"string","enum":["DEVICE","ACCESSORY","EMPLOYEE","ORDER"]}},"options":{"description":"Option catalog. Non-empty only for SELECT / MULTI_SELECT fields. Use option `id` when writing values.","type":"array","items":{"type":"object","properties":{"id":{"description":"Stable UUID of the option. Use this id for SELECT / MULTI_SELECT value writes.","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"value":{"description":"Display label of the option (mutable — ids are the stable identity).","type":"string"}},"required":["id","value"],"additionalProperties":false}}},"required":["id","label","fieldType","applyTo","options"],"additionalProperties":false},"value":{"description":"Current stored value for this field on this order, or null when unset. For SELECT / MULTI_SELECT the value is the option id (or array of ids). For CHECKBOX it is a boolean. For DATE it is an ISO date string.","anyOf":[{"type":"boolean"},{"type":"number"},{"type":"string"},{"type":"array","items":{"type":"string"}},{"type":"null"}]}},"required":["field","value"],"additionalProperties":false}}},"required":["items"],"additionalProperties":false},"SetOrderCustomFieldValueBody":{"type":"object","properties":{"value":{"description":"Value to set. Must conform to the field type. Pass null to clear an existing value. For SELECT supply the option id (string). For MULTI_SELECT supply an array of option ids.","anyOf":[{"type":"boolean"},{"type":"number"},{"type":"string"},{"type":"array","items":{"type":"string"}},{"type":"null"}]}},"required":["value"]},"OrderCustomFieldItem_Output":{"type":"object","properties":{"field":{"type":"object","properties":{"id":{"description":"CustomField id (MongoDB ObjectId string).","type":"string"},"label":{"type":"string"},"fieldType":{"description":"Type of data this field holds.","type":"string","enum":["SELECT","MULTI_SELECT","CHECKBOX","TEXT","DATE","NUMBER","URL","IMAGE"]},"applyTo":{"type":"array","items":{"type":"string","enum":["DEVICE","ACCESSORY","EMPLOYEE","ORDER"]}},"options":{"description":"Option catalog. Non-empty only for SELECT / MULTI_SELECT fields. Use option `id` when writing values.","type":"array","items":{"type":"object","properties":{"id":{"description":"Stable UUID of the option. Use this id for SELECT / MULTI_SELECT value writes.","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"value":{"description":"Display label of the option (mutable — ids are the stable identity).","type":"string"}},"required":["id","value"],"additionalProperties":false}}},"required":["id","label","fieldType","applyTo","options"],"additionalProperties":false},"value":{"description":"Current stored value for this field on this order, or null when unset. For SELECT / MULTI_SELECT the value is the option id (or array of ids). For CHECKBOX it is a boolean. For DATE it is an ISO date string.","anyOf":[{"type":"boolean"},{"type":"number"},{"type":"string"},{"type":"array","items":{"type":"string"}},{"type":"null"}]}},"required":["field","value"],"additionalProperties":false},"CreateEquipmentOrderIntentBody":{"type":"object","properties":{"order":{"description":"Catalog order to place on execute, replaced whole on update. Omit or send null when nothing is purchased.","anyOf":[{"type":"object","properties":{"countryCode":{"description":"Catalog country code (lowercase ISO 3166-1 alpha-2)","type":"string","enum":["af","al","dz","ad","ao","ag","ar","am","au","at","az","bs","bh","bd","bb","by","be","bz","bj","bt","bo","ba","bw","br","bn","bg","bf","bi","cv","kh","cm","ca","cf","td","cl","cn","co","km","cg","cr","hr","cu","cy","cz","cd","dk","dj","dm","do","ec","eg","sv","gq","er","ee","sz","et","fj","fi","fr","ga","gm","ge","de","gh","gr","gd","gt","gn","gw","gy","ht","hn","hu","is","in","id","ir","iq","ie","il","it","jm","jp","jo","kz","ke","ki","kw","kg","la","lv","lb","ls","lr","ly","li","lt","lu","mg","mw","my","mv","ml","mt","mh","mr","mu","mx","fm","md","mc","mn","me","ma","mz","mm","na","nr","np","nl","nz","ni","ne","ng","kp","mk","no","om","pk","pw","pa","pg","py","pe","ph","pl","pt","qa","ro","ru","rw","kn","lc","vc","ws","sm","st","sa","sn","rs","sc","sl","sg","sk","si","sb","so","za","kr","ss","es","lk","sd","sr","se","ch","sy","tw","tj","tz","th","tl","tg","to","tt","tn","tr","tm","tv","ug","ua","ae","gb","us","uy","uz","vu","va","ve","vn","ye","zm","zw"]},"products":{"minItems":1,"type":"array","items":{"type":"object","properties":{"id":{"description":"Catalog product id","type":"string","minLength":1},"variantId":{"description":"Selected product variant id","type":"string","minLength":1},"supplierId":{"description":"Supplier id for this product","type":"string","minLength":1},"hasZTD":{"type":"boolean"},"configuration":{"type":"object","properties":{"enableZTD":{"type":"boolean"},"enableACE":{"type":"boolean"}},"required":["enableZTD","enableACE"]}},"required":["id","variantId","supplierId","configuration"]}},"shippingAddressType":{"description":"Where the address comes from. HOME also back-fills the employee record when it has no address yet, so send it whenever the address is the employee's own.","anyOf":[{"type":"string","enum":["OFFICE","HOME","NEW"]},{"type":"null"}]},"shippingAddress":{"description":"Delivery address. Take it from `getCompanyAddresses` or from the employee record — never compose one.","type":"object","properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}]},"contactName":{"anyOf":[{"type":"string"},{"type":"null"}]},"phone":{"anyOf":[{"type":"string"},{"type":"null"}]},"street":{"type":"string","minLength":1},"complement":{"anyOf":[{"type":"string"},{"type":"null"}]},"postalCode":{"type":"string","minLength":1},"city":{"type":"string","minLength":1},"country":{"anyOf":[{"type":"string"},{"type":"null"}]},"countryCode":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["street","postalCode","city"]},"billingProfileId":{"description":"An eligible company billing profile id from `getBillingProfiles`","anyOf":[{"type":"string","minLength":1},{"type":"null"}]},"notificationEmails":{"type":"array","items":{"type":"string"}},"companyComment":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}]},"appleCareEnterprise":{"anyOf":[{"type":"string"},{"type":"null"}]},"companyPurchaseNumber":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["countryCode","products","shippingAddress"]},{"type":"null"}]},"assignedFromInventory":{"description":"Devices and accessories taken from existing stock and handed over to the employee on execute.","anyOf":[{"type":"object","properties":{"deviceIds":{"default":[],"type":"array","items":{"type":"string","minLength":1}},"accessoryIds":{"default":[],"type":"array","items":{"type":"string","minLength":1}}}},{"type":"null"}]},"automaticEnrollment":{"description":"Send the employee the MDM enrollment request on execute. Defaults to false.","type":"boolean"},"parentTicketId":{"description":"The untyped ticket the order belongs to. Omit it and Primo opens a ticket to hold the task.","anyOf":[{"type":"string","pattern":"^[a-f\\d]{24}$"},{"type":"null"}]},"employeeId":{"description":"Employee the equipment is for (from `getEmployees`). Required to hand over stock; fixed once created.","anyOf":[{"type":"string","pattern":"^[a-f\\d]{24}$"},{"type":"null"}]},"scheduleDate":{"description":"Not supported for an equipment order: refused with `SCHEDULE_NOT_SUPPORTED_FOR_TYPE`. Leave it out and execute the intent when the order is due.","anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]}}},"EquipmentOrderIntent_Output":{"type":"object","properties":{"id":{"type":"string","description":"Intent id — pass it to `updateEquipmentOrderIntent` and `executeEquipmentOrderIntent`"},"taskId":{"description":"The EQUIPMENT_ORDER task that tracks this order","anyOf":[{"type":"string"},{"type":"null"}]},"ticketId":{"description":"The ticket holding that task: the parentTicketId sent, or the one Primo opened. Null if it could not be read back.","anyOf":[{"type":"string"},{"type":"null"}]},"employeeId":{"anyOf":[{"type":"string"},{"type":"null"}]},"order":{"anyOf":[{"type":"object","properties":{"countryCode":{"description":"Catalog country code (lowercase ISO 3166-1 alpha-2)","type":"string","enum":["af","al","dz","ad","ao","ag","ar","am","au","at","az","bs","bh","bd","bb","by","be","bz","bj","bt","bo","ba","bw","br","bn","bg","bf","bi","cv","kh","cm","ca","cf","td","cl","cn","co","km","cg","cr","hr","cu","cy","cz","cd","dk","dj","dm","do","ec","eg","sv","gq","er","ee","sz","et","fj","fi","fr","ga","gm","ge","de","gh","gr","gd","gt","gn","gw","gy","ht","hn","hu","is","in","id","ir","iq","ie","il","it","jm","jp","jo","kz","ke","ki","kw","kg","la","lv","lb","ls","lr","ly","li","lt","lu","mg","mw","my","mv","ml","mt","mh","mr","mu","mx","fm","md","mc","mn","me","ma","mz","mm","na","nr","np","nl","nz","ni","ne","ng","kp","mk","no","om","pk","pw","pa","pg","py","pe","ph","pl","pt","qa","ro","ru","rw","kn","lc","vc","ws","sm","st","sa","sn","rs","sc","sl","sg","sk","si","sb","so","za","kr","ss","es","lk","sd","sr","se","ch","sy","tw","tj","tz","th","tl","tg","to","tt","tn","tr","tm","tv","ug","ua","ae","gb","us","uy","uz","vu","va","ve","vn","ye","zm","zw"]},"products":{"type":"array","items":{"type":"object","properties":{"id":{"description":"Catalog product id","type":"string","minLength":1},"variantId":{"description":"Selected product variant id","type":"string","minLength":1},"supplierId":{"description":"Supplier id for this product","type":"string","minLength":1},"hasZTD":{"type":"boolean"},"configuration":{"type":"object","properties":{"enableZTD":{"type":"boolean"},"enableACE":{"type":"boolean"}},"required":["enableZTD","enableACE"],"additionalProperties":false}},"required":["id","variantId","supplierId","hasZTD","configuration"],"additionalProperties":false}},"shippingAddressType":{"anyOf":[{"type":"string","enum":["OFFICE","HOME","NEW"]},{"type":"null"}]},"shippingAddress":{"description":"Delivery address. Take it from `getCompanyAddresses` or from the employee record — never compose one.","type":"object","properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}]},"contactName":{"anyOf":[{"type":"string"},{"type":"null"}]},"phone":{"anyOf":[{"type":"string"},{"type":"null"}]},"street":{"type":"string","minLength":1},"complement":{"anyOf":[{"type":"string"},{"type":"null"}]},"postalCode":{"type":"string","minLength":1},"city":{"type":"string","minLength":1},"country":{"anyOf":[{"type":"string"},{"type":"null"}]},"countryCode":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["street","postalCode","city"],"additionalProperties":false},"billingProfileId":{"anyOf":[{"type":"string"},{"type":"null"}]},"notificationEmails":{"type":"array","items":{"type":"string"}},"companyComment":{"anyOf":[{"type":"string"},{"type":"null"}]},"appleCareEnterprise":{"anyOf":[{"type":"string"},{"type":"null"}]},"companyPurchaseNumber":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["countryCode","products","shippingAddressType","shippingAddress","billingProfileId","notificationEmails","companyComment","appleCareEnterprise","companyPurchaseNumber"],"additionalProperties":false},{"type":"null"}]},"assignedFromInventory":{"anyOf":[{"type":"object","properties":{"deviceIds":{"default":[],"type":"array","items":{"type":"string","minLength":1}},"accessoryIds":{"default":[],"type":"array","items":{"type":"string","minLength":1}}},"required":["deviceIds","accessoryIds"],"additionalProperties":false},{"type":"null"}]},"automaticEnrollment":{"type":"boolean"},"orderId":{"description":"The order placed on execute, null until then or when nothing was bought","anyOf":[{"type":"string"},{"type":"null"}]},"executedAt":{"description":"When the intent was executed; null while it can still change","anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","taskId","ticketId","employeeId","order","assignedFromInventory","automaticEnrollment","orderId","executedAt","createdAt","updatedAt"],"additionalProperties":false},"UpdateEquipmentOrderIntentBody":{"type":"object","properties":{"order":{"description":"Catalog order to place on execute, replaced whole on update. Omit or send null when nothing is purchased.","anyOf":[{"type":"object","properties":{"countryCode":{"description":"Catalog country code (lowercase ISO 3166-1 alpha-2)","type":"string","enum":["af","al","dz","ad","ao","ag","ar","am","au","at","az","bs","bh","bd","bb","by","be","bz","bj","bt","bo","ba","bw","br","bn","bg","bf","bi","cv","kh","cm","ca","cf","td","cl","cn","co","km","cg","cr","hr","cu","cy","cz","cd","dk","dj","dm","do","ec","eg","sv","gq","er","ee","sz","et","fj","fi","fr","ga","gm","ge","de","gh","gr","gd","gt","gn","gw","gy","ht","hn","hu","is","in","id","ir","iq","ie","il","it","jm","jp","jo","kz","ke","ki","kw","kg","la","lv","lb","ls","lr","ly","li","lt","lu","mg","mw","my","mv","ml","mt","mh","mr","mu","mx","fm","md","mc","mn","me","ma","mz","mm","na","nr","np","nl","nz","ni","ne","ng","kp","mk","no","om","pk","pw","pa","pg","py","pe","ph","pl","pt","qa","ro","ru","rw","kn","lc","vc","ws","sm","st","sa","sn","rs","sc","sl","sg","sk","si","sb","so","za","kr","ss","es","lk","sd","sr","se","ch","sy","tw","tj","tz","th","tl","tg","to","tt","tn","tr","tm","tv","ug","ua","ae","gb","us","uy","uz","vu","va","ve","vn","ye","zm","zw"]},"products":{"minItems":1,"type":"array","items":{"type":"object","properties":{"id":{"description":"Catalog product id","type":"string","minLength":1},"variantId":{"description":"Selected product variant id","type":"string","minLength":1},"supplierId":{"description":"Supplier id for this product","type":"string","minLength":1},"hasZTD":{"type":"boolean"},"configuration":{"type":"object","properties":{"enableZTD":{"type":"boolean"},"enableACE":{"type":"boolean"}},"required":["enableZTD","enableACE"]}},"required":["id","variantId","supplierId","configuration"]}},"shippingAddressType":{"description":"Where the address comes from. HOME also back-fills the employee record when it has no address yet, so send it whenever the address is the employee's own.","anyOf":[{"type":"string","enum":["OFFICE","HOME","NEW"]},{"type":"null"}]},"shippingAddress":{"description":"Delivery address. Take it from `getCompanyAddresses` or from the employee record — never compose one.","type":"object","properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}]},"contactName":{"anyOf":[{"type":"string"},{"type":"null"}]},"phone":{"anyOf":[{"type":"string"},{"type":"null"}]},"street":{"type":"string","minLength":1},"complement":{"anyOf":[{"type":"string"},{"type":"null"}]},"postalCode":{"type":"string","minLength":1},"city":{"type":"string","minLength":1},"country":{"anyOf":[{"type":"string"},{"type":"null"}]},"countryCode":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["street","postalCode","city"]},"billingProfileId":{"description":"An eligible company billing profile id from `getBillingProfiles`","anyOf":[{"type":"string","minLength":1},{"type":"null"}]},"notificationEmails":{"type":"array","items":{"type":"string"}},"companyComment":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}]},"appleCareEnterprise":{"anyOf":[{"type":"string"},{"type":"null"}]},"companyPurchaseNumber":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["countryCode","products","shippingAddress"]},{"type":"null"}]},"assignedFromInventory":{"description":"Devices and accessories taken from existing stock and handed over to the employee on execute.","anyOf":[{"type":"object","properties":{"deviceIds":{"default":[],"type":"array","items":{"type":"string","minLength":1}},"accessoryIds":{"default":[],"type":"array","items":{"type":"string","minLength":1}}}},{"type":"null"}]},"automaticEnrollment":{"description":"Send the employee the MDM enrollment request on execute. Defaults to false.","type":"boolean"}}},"ExecuteEquipmentOrderIntentResult_Output":{"type":"object","properties":{"outcome":{"type":"string","description":"ALREADY_EXECUTED: an earlier call did the work — nothing was ordered or assigned again","enum":["EXECUTED","ALREADY_EXECUTED"]},"intent":{"type":"object","properties":{"id":{"description":"Intent id — pass it to `updateEquipmentOrderIntent` and `executeEquipmentOrderIntent`","type":"string"},"taskId":{"description":"The EQUIPMENT_ORDER task that tracks this order","anyOf":[{"type":"string"},{"type":"null"}]},"ticketId":{"description":"The ticket holding that task: the parentTicketId sent, or the one Primo opened. Null if it could not be read back.","anyOf":[{"type":"string"},{"type":"null"}]},"employeeId":{"anyOf":[{"type":"string"},{"type":"null"}]},"order":{"anyOf":[{"type":"object","properties":{"countryCode":{"description":"Catalog country code (lowercase ISO 3166-1 alpha-2)","type":"string","enum":["af","al","dz","ad","ao","ag","ar","am","au","at","az","bs","bh","bd","bb","by","be","bz","bj","bt","bo","ba","bw","br","bn","bg","bf","bi","cv","kh","cm","ca","cf","td","cl","cn","co","km","cg","cr","hr","cu","cy","cz","cd","dk","dj","dm","do","ec","eg","sv","gq","er","ee","sz","et","fj","fi","fr","ga","gm","ge","de","gh","gr","gd","gt","gn","gw","gy","ht","hn","hu","is","in","id","ir","iq","ie","il","it","jm","jp","jo","kz","ke","ki","kw","kg","la","lv","lb","ls","lr","ly","li","lt","lu","mg","mw","my","mv","ml","mt","mh","mr","mu","mx","fm","md","mc","mn","me","ma","mz","mm","na","nr","np","nl","nz","ni","ne","ng","kp","mk","no","om","pk","pw","pa","pg","py","pe","ph","pl","pt","qa","ro","ru","rw","kn","lc","vc","ws","sm","st","sa","sn","rs","sc","sl","sg","sk","si","sb","so","za","kr","ss","es","lk","sd","sr","se","ch","sy","tw","tj","tz","th","tl","tg","to","tt","tn","tr","tm","tv","ug","ua","ae","gb","us","uy","uz","vu","va","ve","vn","ye","zm","zw"]},"products":{"type":"array","items":{"type":"object","properties":{"id":{"description":"Catalog product id","type":"string","minLength":1},"variantId":{"description":"Selected product variant id","type":"string","minLength":1},"supplierId":{"description":"Supplier id for this product","type":"string","minLength":1},"hasZTD":{"type":"boolean"},"configuration":{"type":"object","properties":{"enableZTD":{"type":"boolean"},"enableACE":{"type":"boolean"}},"required":["enableZTD","enableACE"],"additionalProperties":false}},"required":["id","variantId","supplierId","hasZTD","configuration"],"additionalProperties":false}},"shippingAddressType":{"anyOf":[{"type":"string","enum":["OFFICE","HOME","NEW"]},{"type":"null"}]},"shippingAddress":{"description":"Delivery address. Take it from `getCompanyAddresses` or from the employee record — never compose one.","type":"object","properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}]},"contactName":{"anyOf":[{"type":"string"},{"type":"null"}]},"phone":{"anyOf":[{"type":"string"},{"type":"null"}]},"street":{"type":"string","minLength":1},"complement":{"anyOf":[{"type":"string"},{"type":"null"}]},"postalCode":{"type":"string","minLength":1},"city":{"type":"string","minLength":1},"country":{"anyOf":[{"type":"string"},{"type":"null"}]},"countryCode":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["street","postalCode","city"],"additionalProperties":false},"billingProfileId":{"anyOf":[{"type":"string"},{"type":"null"}]},"notificationEmails":{"type":"array","items":{"type":"string"}},"companyComment":{"anyOf":[{"type":"string"},{"type":"null"}]},"appleCareEnterprise":{"anyOf":[{"type":"string"},{"type":"null"}]},"companyPurchaseNumber":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["countryCode","products","shippingAddressType","shippingAddress","billingProfileId","notificationEmails","companyComment","appleCareEnterprise","companyPurchaseNumber"],"additionalProperties":false},{"type":"null"}]},"assignedFromInventory":{"anyOf":[{"type":"object","properties":{"deviceIds":{"default":[],"type":"array","items":{"type":"string","minLength":1}},"accessoryIds":{"default":[],"type":"array","items":{"type":"string","minLength":1}}},"required":["deviceIds","accessoryIds"],"additionalProperties":false},{"type":"null"}]},"automaticEnrollment":{"type":"boolean"},"orderId":{"description":"The order placed on execute, null until then or when nothing was bought","anyOf":[{"type":"string"},{"type":"null"}]},"executedAt":{"description":"When the intent was executed; null while it can still change","anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","taskId","ticketId","employeeId","order","assignedFromInventory","automaticEnrollment","orderId","executedAt","createdAt","updatedAt"],"additionalProperties":false},"order":{"description":"The order placed for this intent, or null when only stock was handed over","anyOf":[{"type":"object","properties":{"id":{"type":"string"},"reference":{"type":"string"},"status":{"type":"string"}},"required":["id","reference","status"],"additionalProperties":false},{"type":"null"}]}},"required":["outcome","intent","order"],"additionalProperties":false},"GetSaas_Output":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"description":"The company SaaS application ID (companySaasApplicationId). Pass this value as `saasId` to the other SaaS endpoints (getSaasById, getSaasIssues, provision/deprovision, …).","type":"string"},"name":{"type":"string"},"approvalStatus":{"description":"Approval status of the SaaS application in your company. APPROVED is what makes provisioning possible — including manual provisioning, for an application Primo has no integration with. TO_REVIEW and REJECTED applications cannot be provisioned at all.","type":"string","enum":["TO_REVIEW","APPROVED","REJECTED"]},"tags":{"type":"array","items":{"type":"string"}},"connectionStatus":{"description":"State of the API integration between Primo and this application. NOT_CONNECTABLE: Primo has no connector for it. NOT_CONNECTED: a connector exists but your company has not set it up. CONNECTED / DISCONNECTED: your company's connection is live or has lost its credentials. This does NOT say whether the employee can be provisioned: an APPROVED application is provisioned through provisionSaasIdentity whatever this value is — the integration only decides the path, automatic when CONNECTED and a provisioning ticket for an admin otherwise.","type":"string","enum":["CONNECTED","DISCONNECTED","PENDING","NOT_CONNECTED","NOT_CONNECTABLE"]},"identitiesCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"isEmailProvider":{"description":"True on the application the company's mailboxes live in — its email provider. A company has at most one, so this is how you resolve the application behind an email password reset. Everything else is an ordinary SaaS application, whatever its name suggests.","default":false,"type":"boolean"}},"required":["id","name","approvalStatus","tags","connectionStatus","identitiesCount","isEmailProvider"],"additionalProperties":false}},"pagination":{"type":"object","properties":{"totalElements":{"type":"integer","minimum":0,"maximum":9007199254740991},"totalPages":{"type":"integer","minimum":0,"maximum":9007199254740991},"page":{"type":"integer","minimum":1,"maximum":9007199254740991},"perPage":{"type":"integer","minimum":1,"maximum":100}},"required":["totalElements","totalPages","page","perPage"],"additionalProperties":false}},"required":["data","pagination"],"additionalProperties":false},"GetEmployeeSaasIdentities_Output":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"identityId":{"description":"The SaaS identity ID. Pass this value as `identityId` to deprovisionSaasIdentity. This is NOT an employee ID.","type":"string"},"saasId":{"description":"The company SaaS application ID (companySaasApplicationId) this identity belongs to. Pass this value as `saasId` to the other SaaS endpoints (getSaasById, provisionSaasIdentity, …). This is NOT the global catalog saasApplicationId.","type":"string"},"saasName":{"description":"Name of the SaaS application this identity belongs to.","anyOf":[{"type":"string"},{"type":"null"}]},"approvalStatus":{"description":"Approval status of that SaaS application in your company. Only an APPROVED application can be provisioned or deprovisioned — an identity on a TO_REVIEW application is a real access the employee has, discovered by Primo, on an application the company has not approved yet.","anyOf":[{"type":"string","enum":["TO_REVIEW","APPROVED","REJECTED"]},{"type":"null"}]},"email":{"description":"Email of the account on the SaaS side.","type":"string"},"type":{"description":"Nature of the account on the SaaS side, when the provider exposes it.","anyOf":[{"type":"string","enum":["EMPLOYEE","SERVICE","GROUP","GUEST","CONTRACTOR"]},{"type":"null"}]},"groups":{"description":"Groups assigned to this identity.","type":"array","items":{"type":"object","properties":{"id":{"description":"Identifier of this entitlement in the SaaS application — the same value `provisionSaasIdentity` expects in its `groups`, `roles`, `licenses` and `organizationUnits` arrays.","type":"string"},"name":{"description":"Human-readable entitlement name.","type":"string"}},"required":["id","name"],"additionalProperties":false}},"roles":{"description":"Roles assigned to this identity.","type":"array","items":{"type":"object","properties":{"id":{"description":"Identifier of this entitlement in the SaaS application — the same value `provisionSaasIdentity` expects in its `groups`, `roles`, `licenses` and `organizationUnits` arrays.","type":"string"},"name":{"description":"Human-readable entitlement name.","type":"string"}},"required":["id","name"],"additionalProperties":false}},"licenses":{"description":"Licenses assigned to this identity.","type":"array","items":{"type":"object","properties":{"id":{"description":"Identifier of this entitlement in the SaaS application — the same value `provisionSaasIdentity` expects in its `groups`, `roles`, `licenses` and `organizationUnits` arrays.","type":"string"},"name":{"description":"Human-readable entitlement name.","type":"string"}},"required":["id","name"],"additionalProperties":false}},"organizationUnits":{"description":"Organization units assigned to this identity.","type":"array","items":{"type":"object","properties":{"id":{"description":"Identifier of this entitlement in the SaaS application — the same value `provisionSaasIdentity` expects in its `groups`, `roles`, `licenses` and `organizationUnits` arrays.","type":"string"},"name":{"description":"Human-readable entitlement name.","type":"string"}},"required":["id","name"],"additionalProperties":false}},"issues":{"description":"Provisioning issues currently flagged for this identity by the configured SaaS rule.","type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string","enum":["NEED_ACCESS","SHOULD_NOT_HAVE_ACCESS","SHOULD_BE_MEMBER_OF_GROUP","SHOULD_NOT_BE_MEMBER_OF_GROUP","SHOULD_HAVE_ROLE","SHOULD_NOT_HAVE_ROLE","SHOULD_HAVE_LICENSE","SHOULD_NOT_HAVE_LICENSE","SHOULD_BE_IN_ORGANIZATION_UNIT","ORPHANED_IDENTITY"]},"groupId":{"description":"Group involved in the issue, when applicable.","anyOf":[{"type":"string"},{"type":"null"}]},"roleId":{"description":"Role involved in the issue, when applicable.","anyOf":[{"type":"string"},{"type":"null"}]},"licenseId":{"description":"License involved in the issue, when applicable.","anyOf":[{"type":"string"},{"type":"null"}]},"organizationUnitId":{"description":"Organization unit involved in the issue, when applicable.","anyOf":[{"type":"string"},{"type":"null"}]},"reason":{"description":"Plain-language reason for this issue, displayed to the end user.","anyOf":[{"type":"string"},{"type":"null"}]},"createdAt":{"description":"ISO 8601 date-time when the issue was created.","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","type","groupId","roleId","licenseId","organizationUnitId","reason","createdAt"],"additionalProperties":false}}},"required":["identityId","saasId","saasName","approvalStatus","email","type","groups","roles","licenses","organizationUnits","issues"],"additionalProperties":false}}},"required":["data"],"additionalProperties":false},"GetUnlinkedSaasIdentities_Output":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"description":"The SaaS identity ID, to pass to `linkSaasIdentities`, `archiveSaasApplicationUsers` or `deleteSaasApplicationUsers`.","type":"string"},"email":{"description":"Email of the account on the SaaS application.","type":"string"},"firstName":{"anyOf":[{"type":"string"},{"type":"null"}]},"lastName":{"anyOf":[{"type":"string"},{"type":"null"}]},"saasId":{"description":"The company SaaS application the account is on, as `saasId`.","type":"string"},"saasName":{"description":"Display name of that application.","type":"string"},"approvalStatus":{"description":"Approval status of that application in your company.","type":"string","enum":["TO_REVIEW","APPROVED","REJECTED"]},"syncedByIntegration":{"description":"True when an integration syncs that application's accounts into Primo. Archiving or deleting the identity then does not remove the account: the next sync brings it back. The account has to be removed in the application itself, and Primo drops it at the next sync.","type":"boolean"}},"required":["id","email","firstName","lastName","saasId","saasName","approvalStatus","syncedByIntegration"],"additionalProperties":false}},"pagination":{"type":"object","properties":{"totalElements":{"type":"integer","minimum":0,"maximum":9007199254740991},"totalPages":{"type":"integer","minimum":0,"maximum":9007199254740991},"page":{"type":"integer","minimum":1,"maximum":9007199254740991},"perPage":{"type":"integer","minimum":1,"maximum":100}},"required":["totalElements","totalPages","page","perPage"],"additionalProperties":false}},"required":["data","pagination"],"additionalProperties":false},"LinkSaasIdentitiesBody":{"type":"object","properties":{"links":{"description":"The identity → employee pairs to link. Each identity may appear at most once and up to 100 pairs per call. Writes are best-effort: inspect the per-item `results` to learn which succeeded — the HTTP status is 200 even when some items fail.","minItems":1,"maxItems":100,"type":"array","items":{"type":"object","properties":{"saasApplicationUserId":{"description":"The SaaS identity ID, as returned by `getUnlinkedSaasIdentities` → `id` or `getSaasById` → `identities[].id`.","type":"string","pattern":"^[a-f\\d]{24}$"},"employeeId":{"description":"The employee who owns the account, as returned by `getEmployees` → `id`.","type":"string","pattern":"^[a-f\\d]{24}$"}},"required":["saasApplicationUserId","employeeId"]}}},"required":["links"]},"LinkSaasIdentitiesResult_Output":{"type":"object","properties":{"successCount":{"type":"integer","description":"Number of identities linked successfully.","minimum":-9007199254740991,"maximum":9007199254740991},"failureCount":{"type":"integer","description":"Number of identities that failed.","minimum":-9007199254740991,"maximum":9007199254740991},"results":{"type":"array","description":"Per-item outcome, in the same order as the input `links`.","items":{"type":"object","properties":{"status":{"type":"string","enum":["ok","error"]},"errorCode":{"description":"Machine-readable error code when status is \"error\".","anyOf":[{"type":"string"},{"type":"null"}]},"message":{"description":"Human-readable error detail when status is \"error\".","anyOf":[{"type":"string"},{"type":"null"}]},"saasApplicationUserId":{"type":"string"},"employeeId":{"description":"The employee the item targeted, echoed from the input.","type":"string"}},"required":["status","saasApplicationUserId","employeeId"],"additionalProperties":false}}},"required":["successCount","failureCount","results"],"additionalProperties":false},"GetSaasById_Output":{"type":"object","properties":{"id":{"type":"string","description":"The company SaaS application ID (companySaasApplicationId). Pass this value as `saasId` to the other SaaS endpoints (getSaasById, getSaasIssues, provision/deprovision, …)."},"name":{"type":"string"},"approvalStatus":{"type":"string","description":"Approval status of the SaaS application in your company. APPROVED is what makes provisioning possible — including manual provisioning, for an application Primo has no integration with. TO_REVIEW and REJECTED applications cannot be provisioned at all.","enum":["TO_REVIEW","APPROVED","REJECTED"]},"tags":{"type":"array","items":{"type":"string"}},"connectionStatus":{"type":"string","description":"State of the API integration between Primo and this application. NOT_CONNECTABLE: Primo has no connector for it. NOT_CONNECTED: a connector exists but your company has not set it up. CONNECTED / DISCONNECTED: your company's connection is live or has lost its credentials. This does NOT say whether the employee can be provisioned: an APPROVED application is provisioned through provisionSaasIdentity whatever this value is — the integration only decides the path, automatic when CONNECTED and a provisioning ticket for an admin otherwise.","enum":["CONNECTED","DISCONNECTED","PENDING","NOT_CONNECTED","NOT_CONNECTABLE"]},"identitiesCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"isEmailProvider":{"type":"boolean","description":"True on the application the company's mailboxes live in — its email provider. A company has at most one, so this is how you resolve the application behind an email password reset. Everything else is an ordinary SaaS application, whatever its name suggests.","default":false},"identities":{"type":"array","items":{"type":"object","properties":{"id":{"description":"The SaaS identity ID. Pass this value as `identityId` to deprovisionSaasIdentity. This is NOT an employee ID.","type":"string"},"employeeId":{"description":"ID of the Primo employee linked to this identity (same ID as returned by the employee endpoints), or `null` when the identity is not matched to an employee.","anyOf":[{"type":"string"},{"type":"null"}]},"email":{"type":"string"},"groups":{"description":"IDs of groups assigned to this identity.","type":"array","items":{"type":"string"}},"roles":{"description":"IDs of roles assigned to this identity.","type":"array","items":{"type":"string"}},"licenses":{"description":"IDs of licenses assigned to this identity.","type":"array","items":{"type":"string"}},"organizationUnits":{"description":"IDs of organization units assigned to this identity.","type":"array","items":{"type":"string"}},"issues":{"description":"Provisioning issues currently flagged for this identity by the configured SaaS rule.","type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string","enum":["NEED_ACCESS","SHOULD_NOT_HAVE_ACCESS","SHOULD_BE_MEMBER_OF_GROUP","SHOULD_NOT_BE_MEMBER_OF_GROUP","SHOULD_HAVE_ROLE","SHOULD_NOT_HAVE_ROLE","SHOULD_HAVE_LICENSE","SHOULD_NOT_HAVE_LICENSE","SHOULD_BE_IN_ORGANIZATION_UNIT","ORPHANED_IDENTITY"]},"groupId":{"description":"Group involved in the issue, when applicable.","anyOf":[{"type":"string"},{"type":"null"}]},"roleId":{"description":"Role involved in the issue, when applicable.","anyOf":[{"type":"string"},{"type":"null"}]},"licenseId":{"description":"License involved in the issue, when applicable.","anyOf":[{"type":"string"},{"type":"null"}]},"organizationUnitId":{"description":"Organization unit involved in the issue, when applicable.","anyOf":[{"type":"string"},{"type":"null"}]},"reason":{"description":"Plain-language reason for this issue, displayed to the end user.","anyOf":[{"type":"string"},{"type":"null"}]},"createdAt":{"description":"ISO 8601 date-time when the issue was created.","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","type","groupId","roleId","licenseId","organizationUnitId","reason","createdAt"],"additionalProperties":false}}},"required":["id","employeeId","email","groups","roles","licenses","organizationUnits","issues"],"additionalProperties":false}},"recentEvents":{"type":"array","description":"The 20 most synchronization-related recent events for this SaaS integration.","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"description":"Type of event that occurred on this SaaS integration.","type":"string","enum":["USER_PROVISIONED","USER_UPDATED","USER_GROUPS_REPLACED","USER_ROLES_REPLACED","USER_LICENSES_REPLACED","USER_ORGANIZATION_UNITS_REPLACED","USER_DEPROVISIONED","USER_PASSWORD_RESET","SYNCED","GROUPS_SYNCED","ROLES_SYNCED","LICENSES_SYNCED","ORGANIZATION_UNITS_SYNCED","API_CONNECTED","API_DISCONNECTED","AI_AGENT_CONFIGURED","AI_AGENT_DISCONNECTED","SSO_CONNECTED","SSO_DISCONNECTED","SSO_REQUESTED","USER_ACTIVITIES_DISCOVERED"]},"status":{"description":"Outcome status of the event.","type":"string","enum":["PENDING","CANCELLED","SUCCESS","FAILED"]},"createdAt":{"description":"ISO 8601 date-time when the event was created.","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"employeeId":{"description":"Employee involved in the event, if applicable.","anyOf":[{"type":"string"},{"type":"null"}]},"contextType":{"description":"Context in which the event occurred.","anyOf":[{"type":"string","enum":["ONBOARDING","OFFBOARDING","SYNC","USER_ACTIVITIES_DISCOVERY"]},{"type":"null"}]},"errorMessage":{"description":"Error message if the event failed, null otherwise.","anyOf":[{"type":"string"},{"type":"null"}]}},"required":["id","name","status","createdAt","employeeId","contextType","errorMessage"],"additionalProperties":false}},"contract":{"description":"Billing contract currently configured for this SaaS.","anyOf":[{"type":"object","properties":{"pricingMode":{"description":"Contract pricing mode. Use `flat_rate` for one recurring amount or `per_licence` for license-based pricing.","anyOf":[{"type":"string","enum":["per_licence","flat_rate"]},{"type":"null"}]},"currency":{"description":"ISO currency code used for all contract prices.","anyOf":[{"type":"string","enum":["EUR","GBP","USD","CHF","CAD"]},{"type":"null"}]},"billingFrequency":{"description":"Billing period used by every price in this contract: monthly, quarterly, or annual.","anyOf":[{"type":"string","enum":["monthly","quarterly","annual"]},{"type":"null"}]},"flatRatePrice":{"description":"Recurring flat-rate amount billed for one billing period defined by `billingFrequency`. Not annualized. Required when `pricingMode` is `flat_rate`; must be `null` when `pricingMode` is `per_licence`.","anyOf":[{"type":"number"},{"type":"null"}]},"unlicensedPricePerSeat":{"description":"Price billed per unlicensed seat for one billing period defined by `billingFrequency`. Not annualized. Required when `pricingMode` is `per_licence`; must be `null` when `pricingMode` is `flat_rate`.","anyOf":[{"type":"number"},{"type":"null"}]},"unlicensedMinimumSeatsBilled":{"description":"Minimum number of unlicensed seats billed during one billing period. Required when `pricingMode` is `per_licence`; must be `null` when `pricingMode` is `flat_rate`.","anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]},"licenses":{"description":"Priced contract lines, one entry per SaaS license. Required when `pricingMode` is `per_licence`; all `pricePerSeat` and `minimumSeatsBilled` values must be `null` when `pricingMode` is `flat_rate`. The list must exactly match the licenses defined in the SaaS (same `id` for every entry).","type":"array","items":{"type":"object","properties":{"id":{"description":"License identifier used to map this priced contract line to a SaaS license.","type":"string"},"pricePerSeat":{"description":"Price billed per seat for one billing period defined by `billingFrequency`. Not annualized. Required when `pricingMode` is `per_licence`; must be `null` when `pricingMode` is `flat_rate`.","anyOf":[{"type":"number"},{"type":"null"}]},"minimumSeatsBilled":{"description":"Minimum number of seats billed for this license during one billing period. Required when `pricingMode` is `per_licence`; must be `null` when `pricingMode` is `flat_rate`.","anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]}},"required":["id","pricePerSeat","minimumSeatsBilled"],"additionalProperties":false}}},"required":["pricingMode","currency","billingFrequency","flatRatePrice","unlicensedPricePerSeat","unlicensedMinimumSeatsBilled","licenses"],"additionalProperties":false},{"type":"null"}]},"finance":{"type":"object","description":"Derived financial metrics computed from the configured contract.","properties":{"yearlyCost":{"description":"Total SaaS cost annualized from the contract billing frequency.","anyOf":[{"type":"number"},{"type":"null"}]},"unusedYearlyCost":{"description":"Annualized cost of billed but unused seats derived from the current contract configuration.","anyOf":[{"type":"number"},{"type":"null"}]},"unusedSeatsCount":{"description":"Number of billed seats currently unused based on the contract minimums and assigned identities.","anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]}},"required":["yearlyCost","unusedYearlyCost","unusedSeatsCount"],"additionalProperties":false},"licenses":{"type":"array","description":"SaaS license catalog — all available licenses for this SaaS application.","items":{"type":"object","properties":{"id":{"description":"License identifier used to map a SaaS license to a priced contract line.","type":"string"},"name":{"description":"Human-readable license name.","type":"string"}},"required":["id","name"],"additionalProperties":false}},"groups":{"type":"array","description":"All groups available in this SaaS application. Use `id` when provisioning.","items":{"type":"object","properties":{"id":{"description":"Identifier of this group in the SaaS application. Use when provisioning to assign the employee to the correct group.","type":"string"},"name":{"description":"Human-readable group name.","type":"string"}},"required":["id","name"],"additionalProperties":false}},"roles":{"type":"array","description":"All roles available in this SaaS application. Use `id` when provisioning.","items":{"type":"object","properties":{"id":{"description":"Identifier of this role in the SaaS application. Use when provisioning to assign the correct role.","type":"string"},"name":{"description":"Human-readable role name.","type":"string"},"description":{"description":"Optional description of the role.","anyOf":[{"type":"string"},{"type":"null"}]}},"required":["id","name","description"],"additionalProperties":false}},"organizationUnits":{"type":"array","description":"All organization units available in this SaaS application. Use `id` when provisioning.","items":{"type":"object","properties":{"id":{"description":"Identifier of this organization unit in the SaaS application. Use when provisioning to assign the correct unit.","type":"string"},"name":{"description":"Human-readable organization unit name.","type":"string"}},"required":["id","name"],"additionalProperties":false}},"rule":{"description":"Provisioning rule configured for this SaaS, or null if no rule has been authored yet.","anyOf":[{"type":"object","properties":{"draft":{"description":"The editable draft prompt for this SaaS provisioning rule. This is the text updateSaasRule writes.","type":"string"},"published":{"description":"The prompt the agent evaluates at runtime when reviewing provisioning for this SaaS, or null if never published. Diff it against the draft to surface pending edits.","anyOf":[{"type":"string"},{"type":"null"}]},"status":{"description":"Publication state. \"unpublished\": never published (or hidden). \"pending-changes\": the draft has edits not yet published. \"published\": the draft matches the published text.","type":"string","enum":["unpublished","pending-changes","published"]}},"required":["draft","published","status"],"additionalProperties":false},{"type":"null"}]}},"required":["id","name","approvalStatus","tags","connectionStatus","identitiesCount","isEmailProvider","identities","recentEvents","contract","finance","licenses","groups","roles","organizationUnits","rule"],"additionalProperties":false},"GetSaasIssues_Output":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string","enum":["NEED_ACCESS","SHOULD_NOT_HAVE_ACCESS","SHOULD_BE_MEMBER_OF_GROUP","SHOULD_NOT_BE_MEMBER_OF_GROUP","SHOULD_HAVE_ROLE","SHOULD_NOT_HAVE_ROLE","SHOULD_HAVE_LICENSE","SHOULD_NOT_HAVE_LICENSE","SHOULD_BE_IN_ORGANIZATION_UNIT","ORPHANED_IDENTITY"]},"employeeId":{"description":"Primo employee involved in the issue, when applicable.","anyOf":[{"type":"string"},{"type":"null"}]},"identityId":{"description":"Identity involved in the issue, when applicable.","anyOf":[{"type":"string"},{"type":"null"}]},"groupId":{"description":"Group involved in the issue, when applicable.","anyOf":[{"type":"string"},{"type":"null"}]},"roleId":{"description":"Role involved in the issue, when applicable.","anyOf":[{"type":"string"},{"type":"null"}]},"licenseId":{"description":"License involved in the issue, when applicable.","anyOf":[{"type":"string"},{"type":"null"}]},"organizationUnitId":{"description":"Organization unit involved in the issue, when applicable.","anyOf":[{"type":"string"},{"type":"null"}]},"reason":{"description":"Plain-language reason for this issue, displayed to the end user.","anyOf":[{"type":"string"},{"type":"null"}]},"createdAt":{"description":"ISO 8601 date-time when the issue was created.","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","type","employeeId","identityId","groupId","roleId","licenseId","organizationUnitId","reason","createdAt"],"additionalProperties":false}}},"required":["data"],"additionalProperties":false},"UpdateSaasContractBody":{"type":"object","properties":{"pricingMode":{"description":"Contract pricing mode. Use `flat_rate` for one recurring amount or `per_licence` for license-based pricing.","anyOf":[{"type":"string","enum":["per_licence","flat_rate"]},{"type":"null"}]},"currency":{"description":"ISO currency code used for all contract prices.","anyOf":[{"type":"string","enum":["EUR","GBP","USD","CHF","CAD"]},{"type":"null"}]},"billingFrequency":{"description":"Billing period used by every price in this contract: monthly, quarterly, or annual.","anyOf":[{"type":"string","enum":["monthly","quarterly","annual"]},{"type":"null"}]},"flatRatePrice":{"description":"Recurring flat-rate amount billed for one billing period defined by `billingFrequency`. Not annualized. Required when `pricingMode` is `flat_rate`; must be `null` when `pricingMode` is `per_licence`.","anyOf":[{"type":"number"},{"type":"null"}]},"unlicensedPricePerSeat":{"description":"Price billed per unlicensed seat for one billing period defined by `billingFrequency`. Not annualized. Required when `pricingMode` is `per_licence`; must be `null` when `pricingMode` is `flat_rate`.","anyOf":[{"type":"number"},{"type":"null"}]},"unlicensedMinimumSeatsBilled":{"description":"Minimum number of unlicensed seats billed during one billing period. Required when `pricingMode` is `per_licence`; must be `null` when `pricingMode` is `flat_rate`.","anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]},"licenses":{"description":"Priced contract lines, one entry per SaaS license. Required when `pricingMode` is `per_licence`; all `pricePerSeat` and `minimumSeatsBilled` values must be `null` when `pricingMode` is `flat_rate`. The list must exactly match the licenses defined in the SaaS (same `id` for every entry).","type":"array","items":{"type":"object","properties":{"id":{"description":"License identifier used to map this priced contract line to a SaaS license.","type":"string"},"pricePerSeat":{"description":"Price billed per seat for one billing period defined by `billingFrequency`. Not annualized. Required when `pricingMode` is `per_licence`; must be `null` when `pricingMode` is `flat_rate`.","anyOf":[{"type":"number"},{"type":"null"}]},"minimumSeatsBilled":{"description":"Minimum number of seats billed for this license during one billing period. Required when `pricingMode` is `per_licence`; must be `null` when `pricingMode` is `flat_rate`.","anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]}},"required":["id","pricePerSeat","minimumSeatsBilled"]}}},"required":["pricingMode","currency","billingFrequency","flatRatePrice","unlicensedPricePerSeat","unlicensedMinimumSeatsBilled","licenses"]},"SaasContractResource_Output":{"type":"object","properties":{"contract":{"description":"Billing contract currently configured for this SaaS.","anyOf":[{"type":"object","properties":{"pricingMode":{"description":"Contract pricing mode. Use `flat_rate` for one recurring amount or `per_licence` for license-based pricing.","anyOf":[{"type":"string","enum":["per_licence","flat_rate"]},{"type":"null"}]},"currency":{"description":"ISO currency code used for all contract prices.","anyOf":[{"type":"string","enum":["EUR","GBP","USD","CHF","CAD"]},{"type":"null"}]},"billingFrequency":{"description":"Billing period used by every price in this contract: monthly, quarterly, or annual.","anyOf":[{"type":"string","enum":["monthly","quarterly","annual"]},{"type":"null"}]},"flatRatePrice":{"description":"Recurring flat-rate amount billed for one billing period defined by `billingFrequency`. Not annualized. Required when `pricingMode` is `flat_rate`; must be `null` when `pricingMode` is `per_licence`.","anyOf":[{"type":"number"},{"type":"null"}]},"unlicensedPricePerSeat":{"description":"Price billed per unlicensed seat for one billing period defined by `billingFrequency`. Not annualized. Required when `pricingMode` is `per_licence`; must be `null` when `pricingMode` is `flat_rate`.","anyOf":[{"type":"number"},{"type":"null"}]},"unlicensedMinimumSeatsBilled":{"description":"Minimum number of unlicensed seats billed during one billing period. Required when `pricingMode` is `per_licence`; must be `null` when `pricingMode` is `flat_rate`.","anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]},"licenses":{"description":"Priced contract lines, one entry per SaaS license. Required when `pricingMode` is `per_licence`; all `pricePerSeat` and `minimumSeatsBilled` values must be `null` when `pricingMode` is `flat_rate`. The list must exactly match the licenses defined in the SaaS (same `id` for every entry).","type":"array","items":{"type":"object","properties":{"id":{"description":"License identifier used to map this priced contract line to a SaaS license.","type":"string"},"pricePerSeat":{"description":"Price billed per seat for one billing period defined by `billingFrequency`. Not annualized. Required when `pricingMode` is `per_licence`; must be `null` when `pricingMode` is `flat_rate`.","anyOf":[{"type":"number"},{"type":"null"}]},"minimumSeatsBilled":{"description":"Minimum number of seats billed for this license during one billing period. Required when `pricingMode` is `per_licence`; must be `null` when `pricingMode` is `flat_rate`.","anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]}},"required":["id","pricePerSeat","minimumSeatsBilled"],"additionalProperties":false}}},"required":["pricingMode","currency","billingFrequency","flatRatePrice","unlicensedPricePerSeat","unlicensedMinimumSeatsBilled","licenses"],"additionalProperties":false},{"type":"null"}]},"finance":{"type":"object","description":"Derived financial metrics computed from the configured contract.","properties":{"yearlyCost":{"description":"Total SaaS cost annualized from the contract billing frequency.","anyOf":[{"type":"number"},{"type":"null"}]},"unusedYearlyCost":{"description":"Annualized cost of billed but unused seats derived from the current contract configuration.","anyOf":[{"type":"number"},{"type":"null"}]},"unusedSeatsCount":{"description":"Number of billed seats currently unused based on the contract minimums and assigned identities.","anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]}},"required":["yearlyCost","unusedYearlyCost","unusedSeatsCount"],"additionalProperties":false},"licenses":{"type":"array","description":"SaaS license catalog — all available licenses for this SaaS application.","items":{"type":"object","properties":{"id":{"description":"License identifier used to map a SaaS license to a priced contract line.","type":"string"},"name":{"description":"Human-readable license name.","type":"string"}},"required":["id","name"],"additionalProperties":false}},"groups":{"type":"array","description":"All groups available in this SaaS application. Use `id` when provisioning.","items":{"type":"object","properties":{"id":{"description":"Identifier of this group in the SaaS application. Use when provisioning to assign the employee to the correct group.","type":"string"},"name":{"description":"Human-readable group name.","type":"string"}},"required":["id","name"],"additionalProperties":false}},"roles":{"type":"array","description":"All roles available in this SaaS application. Use `id` when provisioning.","items":{"type":"object","properties":{"id":{"description":"Identifier of this role in the SaaS application. Use when provisioning to assign the correct role.","type":"string"},"name":{"description":"Human-readable role name.","type":"string"},"description":{"description":"Optional description of the role.","anyOf":[{"type":"string"},{"type":"null"}]}},"required":["id","name","description"],"additionalProperties":false}},"organizationUnits":{"type":"array","description":"All organization units available in this SaaS application. Use `id` when provisioning.","items":{"type":"object","properties":{"id":{"description":"Identifier of this organization unit in the SaaS application. Use when provisioning to assign the correct unit.","type":"string"},"name":{"description":"Human-readable organization unit name.","type":"string"}},"required":["id","name"],"additionalProperties":false}}},"required":["contract","finance","licenses","groups","roles","organizationUnits"],"additionalProperties":false},"UpdateSaasRuleBody":{"type":"object","properties":{"content":{"description":"The COMPLETE new provisioning rule text. This fully replaces the draft — it is not appended.","type":"string"},"publish":{"description":"Set to true to publish the rule in the same call: the draft is written and immediately copied to the published text the agent reads at runtime. Use it when the user has already confirmed the change — a unitary request such as \"block anyone outside Finance from admin access\" is that confirmation — so one edit costs one approval instead of two. Leave it out for an open-ended rewrite the user has not seen yet: the draft is saved and stays offline until publishSaasRule.","type":"boolean"}},"required":["content"]},"SaasRule_Output":{"type":"object","properties":{"rule":{"description":"Provisioning rule configured for this SaaS, or null if no rule has been authored yet.","anyOf":[{"type":"object","properties":{"draft":{"description":"The editable draft prompt for this SaaS provisioning rule. This is the text updateSaasRule writes.","type":"string"},"published":{"description":"The prompt the agent evaluates at runtime when reviewing provisioning for this SaaS, or null if never published. Diff it against the draft to surface pending edits.","anyOf":[{"type":"string"},{"type":"null"}]},"status":{"description":"Publication state. \"unpublished\": never published (or hidden). \"pending-changes\": the draft has edits not yet published. \"published\": the draft matches the published text.","type":"string","enum":["unpublished","pending-changes","published"]}},"required":["draft","published","status"],"additionalProperties":false},{"type":"null"}]}},"required":["rule"],"additionalProperties":false},"PreviewSaasIdentitiesBody":{"type":"object","properties":{"firstName":{"description":"First name of the person.","type":"string","minLength":1},"lastName":{"description":"Last name of the person.","type":"string","minLength":1},"email":{"description":"An email address of the person.","type":"string","minLength":1},"teams":{"description":"Names of the teams the person is in, as the company writes them. A team that does not exist in Primo yet is fine.","type":"array","items":{"type":"string","minLength":1}},"jobs":{"description":"Job titles of the person. A title that does not exist in Primo yet is fine.","type":"array","items":{"type":"string","minLength":1}},"workLocation":{"description":"Name of the work location, e.g. an office or a city.","type":"string","minLength":1},"legalEntity":{"description":"Name of the legal entity that employs the person.","type":"string","minLength":1},"managerFullName":{"description":"Full name of the person's manager.","type":"string","minLength":1},"employmentType":{"description":"Kind of contract, e.g. permanent, contractor, intern.","type":"string","minLength":1},"customFields":{"description":"The person's employee custom field values. The rules read them by the field's label.","type":"array","items":{"type":"object","properties":{"customFieldId":{"description":"Id of an active employee custom field, as listed by `getEmployeeCustomFields` → `field.id`.","type":"string","minLength":1},"value":{"description":"Value in the same shape `setEmployeeCustomFieldValue` takes: an option id for SELECT, an array of option ids for MULTI_SELECT, a boolean for CHECKBOX, a number for NUMBER, a string otherwise.","anyOf":[{"type":"boolean"},{"type":"number"},{"type":"string"},{"type":"array","items":{"type":"string"}}]}},"required":["customFieldId","value"]}}}},"PreviewSaasIdentities_Output":{"type":"object","properties":{"data":{"type":"array","description":"One entry per APPROVED application whose published rule grants the person an account. An application the rules do not grant is absent.","items":{"type":"object","properties":{"saasId":{"description":"The company SaaS application ID. Pass it as `saasId` to `provisionSaasIdentity` or `getSaasById`. This is NOT the global catalog saasApplicationId.","type":"string"},"saasName":{"description":"Name of the SaaS application.","anyOf":[{"type":"string"},{"type":"null"}]},"groups":{"description":"Groups the rule grants.","type":"array","items":{"type":"object","properties":{"id":{"description":"Identifier of this entitlement in the SaaS application — the same value `provisionSaasIdentity` expects in its `groups`, `roles`, `licenses` and `organizationUnits` arrays.","type":"string"},"name":{"description":"Human-readable entitlement name.","type":"string"}},"required":["id","name"],"additionalProperties":false}},"roles":{"description":"Roles the rule grants.","type":"array","items":{"type":"object","properties":{"id":{"description":"Identifier of this entitlement in the SaaS application — the same value `provisionSaasIdentity` expects in its `groups`, `roles`, `licenses` and `organizationUnits` arrays.","type":"string"},"name":{"description":"Human-readable entitlement name.","type":"string"}},"required":["id","name"],"additionalProperties":false}},"licenses":{"description":"Licenses the rule grants. A licence is a billed seat: its price is on `getSaasById` → `contract`.","type":"array","items":{"type":"object","properties":{"id":{"description":"Identifier of this entitlement in the SaaS application — the same value `provisionSaasIdentity` expects in its `groups`, `roles`, `licenses` and `organizationUnits` arrays.","type":"string"},"name":{"description":"Human-readable entitlement name.","type":"string"}},"required":["id","name"],"additionalProperties":false}},"organizationUnits":{"description":"Organization units the rule grants.","type":"array","items":{"type":"object","properties":{"id":{"description":"Identifier of this entitlement in the SaaS application — the same value `provisionSaasIdentity` expects in its `groups`, `roles`, `licenses` and `organizationUnits` arrays.","type":"string"},"name":{"description":"Human-readable entitlement name.","type":"string"}},"required":["id","name"],"additionalProperties":false}}},"required":["saasId","saasName","groups","roles","licenses","organizationUnits"],"additionalProperties":false}}},"required":["data"],"additionalProperties":false},"PreviewSaasIssues_Output":{"type":"object","properties":{"compliantCount":{"type":"integer","description":"Current employees the draft flags nothing for.","minimum":-9007199254740991,"maximum":9007199254740991},"data":{"type":"array","description":"One entry per employee or identity the draft flags; compliant employees are left out.","items":{"type":"object","properties":{"employeeId":{"description":"Employee the entry is about, or `null` for an orphaned identity.","anyOf":[{"type":"string"},{"type":"null"}]},"name":{"description":"Full name of the employee, else the email of the identity.","anyOf":[{"type":"string"},{"type":"null"}]},"issues":{"description":"What the draft would flag for this person.","type":"array","items":{"type":"object","properties":{"type":{"type":"string","enum":["NEED_ACCESS","SHOULD_NOT_HAVE_ACCESS","SHOULD_BE_MEMBER_OF_GROUP","SHOULD_NOT_BE_MEMBER_OF_GROUP","SHOULD_HAVE_ROLE","SHOULD_NOT_HAVE_ROLE","SHOULD_HAVE_LICENSE","SHOULD_NOT_HAVE_LICENSE","SHOULD_BE_IN_ORGANIZATION_UNIT","ORPHANED_IDENTITY"]},"identityId":{"description":"Account of the person the issue is about, or `null` when the person has no account on the SaaS.","anyOf":[{"type":"string"},{"type":"null"}]},"groupId":{"description":"Group involved in the issue, when applicable.","anyOf":[{"type":"string"},{"type":"null"}]},"roleId":{"description":"Role involved in the issue, when applicable.","anyOf":[{"type":"string"},{"type":"null"}]},"licenseId":{"description":"License involved in the issue, when applicable.","anyOf":[{"type":"string"},{"type":"null"}]},"organizationUnitId":{"description":"Organization unit involved in the issue, when applicable.","anyOf":[{"type":"string"},{"type":"null"}]},"resourceName":{"description":"Name of the group, role, license or organization unit involved, when applicable.","anyOf":[{"type":"string"},{"type":"null"}]}},"required":["type","identityId","groupId","roleId","licenseId","organizationUnitId","resourceName"],"additionalProperties":false}}},"required":["employeeId","name","issues"],"additionalProperties":false}}},"required":["compliantCount","data"],"additionalProperties":false},"ProvisionSaasIdentityBody":{"type":"object","properties":{"employeeId":{"description":"The Primo employee ID to provision on this SaaS application, as returned by the employee endpoints (`id` field). This is NOT a SaaS identity ID.","type":"string"},"groups":{"description":"IDs of groups to assign. Retrieve available IDs from `getSaasById` → `groups[].id`.","type":"array","items":{"type":"string","minLength":1}},"roles":{"description":"IDs of roles to assign. Retrieve available IDs from `getSaasById` → `roles[].id`.","type":"array","items":{"type":"string","minLength":1}},"licenses":{"description":"IDs of licenses to assign. Retrieve available IDs from `getSaasById` → `licenses[].id`.","type":"array","items":{"type":"string","minLength":1}},"organizationUnits":{"description":"Organization units the account belongs to, as IDs from `getSaasById` → `organizationUnits[].id`.","type":"array","items":{"type":"string","minLength":1}},"ticketId":{"description":"The ticket the request came from. When the application has to be provisioned by hand, the task for the admin is added to this ticket instead of opening a new provisioning ticket.","type":"string","pattern":"^[a-f\\d]{24}$"}},"required":["employeeId"]},"ProvisionSaasIdentity_Output":{"type":"object","properties":{"provisioningType":{"type":"string","description":"Whether the provisioning was handled automatically via API or a manual ticket was created.","enum":["automatic","manual"]}},"required":["provisioningType"],"additionalProperties":false},"CreateSaasProvisioningIntentBody":{"type":"object","properties":{"employeeId":{"description":"The Primo employee the account is for (`id` from the employee endpoints).","type":"string","pattern":"^[a-f\\d]{24}$"},"direction":{"description":"PROVISION creates the account, DEPROVISION removes it, UPDATE re-applies the entitlements on it.","type":"string","enum":["PROVISION","DEPROVISION","UPDATE"]},"identityId":{"description":"The SaaS identity to update or remove (from `getEmployeeSaasIdentities`). Required for UPDATE.","anyOf":[{"type":"string","pattern":"^[a-f\\d]{24}$"},{"type":"null"}]},"groups":{"type":"array","items":{"type":"object","properties":{"id":{"description":"The entitlement id from `getSaasById`, or null for one only an admin knows by name","anyOf":[{"type":"string"},{"type":"null"}]},"name":{"type":"string","minLength":1}},"required":["id","name"]}},"roles":{"type":"array","items":{"type":"object","properties":{"id":{"description":"The entitlement id from `getSaasById`, or null for one only an admin knows by name","anyOf":[{"type":"string"},{"type":"null"}]},"name":{"type":"string","minLength":1}},"required":["id","name"]}},"licenses":{"type":"array","items":{"type":"object","properties":{"id":{"description":"The entitlement id from `getSaasById`, or null for one only an admin knows by name","anyOf":[{"type":"string"},{"type":"null"}]},"name":{"type":"string","minLength":1}},"required":["id","name"]}},"organizationUnits":{"type":"array","items":{"type":"object","properties":{"id":{"description":"The entitlement id from `getSaasById`, or null for one only an admin knows by name","anyOf":[{"type":"string"},{"type":"null"}]},"name":{"type":"string","minLength":1}},"required":["id","name"]}},"parentTicketId":{"description":"The untyped ticket the work belongs to, such as the onboarding ticket. Omit it and Primo opens one.","anyOf":[{"type":"string","pattern":"^[a-f\\d]{24}$"},{"type":"null"}]},"scheduleDate":{"description":"Creates the task SCHEDULED: an integrated application is provisioned when it wakes on this date, not now.","anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]}},"required":["employeeId","direction"]},"SaasProvisioningIntent_Output":{"type":"object","properties":{"id":{"type":"string","description":"Intent id"},"taskId":{"description":"The SAAS_PROVISIONING task that tracks the account","anyOf":[{"type":"string"},{"type":"null"}]},"ticketId":{"type":"string","description":"The ticket holding that task: the parentTicketId sent, or the one Primo opened"},"employeeId":{"type":"string"},"saasId":{"type":"string"},"direction":{"type":"string","enum":["PROVISION","DEPROVISION","UPDATE"]},"identityId":{"anyOf":[{"type":"string"},{"type":"null"}]},"groups":{"type":"array","items":{"type":"object","properties":{"id":{"description":"The entitlement id from `getSaasById`, or null for one only an admin knows by name","anyOf":[{"type":"string"},{"type":"null"}]},"name":{"type":"string","minLength":1}},"required":["id","name"],"additionalProperties":false}},"roles":{"type":"array","items":{"type":"object","properties":{"id":{"description":"The entitlement id from `getSaasById`, or null for one only an admin knows by name","anyOf":[{"type":"string"},{"type":"null"}]},"name":{"type":"string","minLength":1}},"required":["id","name"],"additionalProperties":false}},"licenses":{"type":"array","items":{"type":"object","properties":{"id":{"description":"The entitlement id from `getSaasById`, or null for one only an admin knows by name","anyOf":[{"type":"string"},{"type":"null"}]},"name":{"type":"string","minLength":1}},"required":["id","name"],"additionalProperties":false}},"organizationUnits":{"type":"array","items":{"type":"object","properties":{"id":{"description":"The entitlement id from `getSaasById`, or null for one only an admin knows by name","anyOf":[{"type":"string"},{"type":"null"}]},"name":{"type":"string","minLength":1}},"required":["id","name"],"additionalProperties":false}},"executedAt":{"description":"When Primo carried the account out; null while it waits on its date or on the admin","anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","taskId","ticketId","employeeId","saasId","direction","identityId","groups","roles","licenses","organizationUnits","executedAt","createdAt"],"additionalProperties":false},"DeprovisionSaasIdentityBody":{"type":"object","properties":{"identityId":{"description":"The ID of the identity to deprovision. Retrieve it from `getSaasById` → `identities[].id`.","type":"string","minLength":1}},"required":["identityId"]},"DeprovisionSaasIdentity_Output":{"type":"object","properties":{"provisioningType":{"type":"string","description":"Whether the deprovisioning was handled automatically via API or a manual ticket was created.","enum":["automatic","manual"]}},"required":["provisioningType"],"additionalProperties":false},"ResetSaasIdentityPasswordBody":{"type":"object","properties":{"employeeId":{"description":"The Primo employee ID whose identity on this SaaS application gets a new password, as returned by the employee endpoints (`id` field). This is NOT a SaaS identity ID.","type":"string","minLength":1}},"required":["employeeId"]},"ResetSaasIdentityPassword_Output":{"type":"object","properties":{"recipientType":{"type":"string","description":"Which address the new password was sent to. The address itself is never returned — say \"your personal email address\" rather than spelling it out.","enum":["personal","professional"]},"deliveryStatus":{"type":"string","description":"`delivered` when the email left for the recipient. `failed` means the password WAS changed at the provider but the email did not go out: the identity is locked out and a human has to restore access.","enum":["delivered","failed"]},"saasApplicationName":{"type":"string","description":"Name of the SaaS application whose password was reset."}},"required":["recipientType","deliveryStatus","saasApplicationName"],"additionalProperties":false},"CreateSaasIdentityBody":{"type":"object","properties":{"employeeId":{"description":"The Primo employee ID the identity belongs to, as returned by the employee endpoints (`id` field). When set, the identity is linked to that employee and its email is taken from the employee record. This is NOT a SaaS identity ID.","type":"string","minLength":1},"email":{"description":"Email of the account on the SaaS application. Required when `employeeId` is omitted; ignored when `employeeId` is set, since the employee email is used instead.","type":"string","format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},"groups":{"description":"Groups the account belongs to, as IDs from `getSaasById` → `groups[].id`.","type":"array","items":{"type":"string","minLength":1}},"roles":{"description":"Roles the account holds, as IDs from `getSaasById` → `roles[].id`.","type":"array","items":{"type":"string","minLength":1}},"licenses":{"description":"Licenses the account holds, as IDs from `getSaasById` → `licenses[].id`.","type":"array","items":{"type":"string","minLength":1}},"organizationUnits":{"description":"Organization units the account belongs to, as IDs from `getSaasById` → `organizationUnits[].id`.","type":"array","items":{"type":"string","minLength":1}}}},"CreateSaasIdentity_Output":{"type":"object","properties":{"id":{"type":"string","description":"The created SaaS identity ID. Pass this value as `saasApplicationUserId` to `archiveSaasApplicationUser` or `deleteSaasApplicationUser`."}},"required":["id"],"additionalProperties":false},"UpdateSaasOwnerBody":{"type":"object","properties":{"ownerId":{"description":"Employee ID of the new SaaS application owner.","type":"string","minLength":1}},"required":["ownerId"]},"UpdateSaasOwnerResult_Output":{"type":"object","properties":{"id":{"type":"string","description":"Company SaaS application ID."},"ownerId":{"description":"Employee ID of the SaaS application owner.","anyOf":[{"type":"string"},{"type":"null"}]}},"required":["id","ownerId"],"additionalProperties":false},"UpdateSaasApprovalStatusBody":{"type":"object","properties":{"approvalStatus":{"description":"New approval status of the SaaS application. Setting it to `APPROVED` also enables manual provisioning.","type":"string","enum":["TO_REVIEW","APPROVED","REJECTED"]}},"required":["approvalStatus"]},"UpdateSaasApprovalStatusResult_Output":{"type":"object","properties":{"id":{"type":"string","description":"Company SaaS application ID."},"approvalStatus":{"type":"string","enum":["TO_REVIEW","APPROVED","REJECTED"]},"manualProvisioningEnabled":{"type":"boolean","description":"Whether manual provisioning is enabled (true when the approval status is `APPROVED`)."}},"required":["id","approvalStatus","manualProvisioningEnabled"],"additionalProperties":false},"SaasIdentityEntitlementAssignment_Output":{"type":"object","properties":{"changed":{"type":"boolean","description":"False when the identity already stood as asked — the entitlement was already assigned, or already absent. Nothing was sent to the application in that case."},"provisioningType":{"description":"How the change is being applied: `automatic` when the integration carries it out, `manual` when a provisioning ticket was raised for an admin. `null` when nothing changed.","anyOf":[{"type":"string","enum":["automatic","manual"]},{"type":"null"}]}},"required":["changed","provisioningType"],"additionalProperties":false},"SaasEntitlementMutationBody":{"type":"object","properties":{"name":{"description":"Display name of the entitlement.","type":"string","minLength":1}},"required":["name"]},"SaasEntitlementList_Output":{"type":"object","properties":{"entitlements":{"type":"array","description":"Full list of entitlements of this type for the SaaS after the change.","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false}}},"required":["entitlements"],"additionalProperties":false},"SaasApplicationUserMutationResult_Output":{"type":"object","properties":{"success":{"type":"boolean"}},"required":["success"],"additionalProperties":false},"SaasApplicationUsersBatchBody":{"type":"object","properties":{"saasApplicationUserIds":{"description":"The identity IDs to act on, as returned by `getSaasById` → `identities[].id`. Each ID may appear at most once and up to 100 per call. Writes are best-effort: inspect the per-item `results` to learn which succeeded — the HTTP status is 200 even when some items fail.","minItems":1,"maxItems":100,"type":"array","items":{"type":"string","minLength":1}}},"required":["saasApplicationUserIds"]},"SaasApplicationUsersBatchResult_Output":{"type":"object","properties":{"successCount":{"type":"integer","description":"Number of identities processed successfully.","minimum":-9007199254740991,"maximum":9007199254740991},"failureCount":{"type":"integer","description":"Number of identities that failed.","minimum":-9007199254740991,"maximum":9007199254740991},"results":{"type":"array","description":"Per-item outcome, in the same order as the input `saasApplicationUserIds`.","items":{"type":"object","properties":{"status":{"type":"string","enum":["ok","error"]},"errorCode":{"description":"Machine-readable error code when status is \"error\".","anyOf":[{"type":"string"},{"type":"null"}]},"message":{"description":"Human-readable error detail when status is \"error\".","anyOf":[{"type":"string"},{"type":"null"}]},"saasApplicationUserId":{"type":"string"}},"required":["status","saasApplicationUserId"],"additionalProperties":false}}},"required":["successCount","failureCount","results"],"additionalProperties":false},"CreateSaasIdentitiesBody":{"type":"object","properties":{"items":{"description":"The identities to record, each carrying the same fields as `createSaasIdentity`. Up to 100 items per call, each employee or email at most once. Writes are best-effort: inspect the per-item `results` to learn which succeeded.","minItems":1,"maxItems":100,"type":"array","items":{"type":"object","properties":{"employeeId":{"description":"The Primo employee ID the identity belongs to, as returned by the employee endpoints (`id` field). When set, the identity is linked to that employee and its email is taken from the employee record. This is NOT a SaaS identity ID.","type":"string","minLength":1},"email":{"description":"Email of the account on the SaaS application. Required when `employeeId` is omitted; ignored when `employeeId` is set, since the employee email is used instead.","type":"string","format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},"groups":{"description":"Groups the account belongs to, as IDs from `getSaasById` → `groups[].id`.","type":"array","items":{"type":"string","minLength":1}},"roles":{"description":"Roles the account holds, as IDs from `getSaasById` → `roles[].id`.","type":"array","items":{"type":"string","minLength":1}},"licenses":{"description":"Licenses the account holds, as IDs from `getSaasById` → `licenses[].id`.","type":"array","items":{"type":"string","minLength":1}},"organizationUnits":{"description":"Organization units the account belongs to, as IDs from `getSaasById` → `organizationUnits[].id`.","type":"array","items":{"type":"string","minLength":1}}}}}},"required":["items"]},"CreateSaasIdentitiesResult_Output":{"type":"object","properties":{"successCount":{"type":"integer","description":"Number of identities created successfully.","minimum":-9007199254740991,"maximum":9007199254740991},"failureCount":{"type":"integer","description":"Number of identities that failed.","minimum":-9007199254740991,"maximum":9007199254740991},"results":{"type":"array","description":"Per-item outcome, in the same order as the input `items`.","items":{"type":"object","properties":{"status":{"type":"string","enum":["ok","error"]},"errorCode":{"description":"Machine-readable error code when status is \"error\".","anyOf":[{"type":"string"},{"type":"null"}]},"message":{"description":"Human-readable error detail when status is \"error\".","anyOf":[{"type":"string"},{"type":"null"}]},"employeeId":{"description":"The employee the item targeted, echoed from the input.","anyOf":[{"type":"string"},{"type":"null"}]},"email":{"description":"The email the item targeted, echoed from the input.","anyOf":[{"type":"string"},{"type":"null"}]},"id":{"description":"The created SaaS identity ID when status is \"ok\".","anyOf":[{"type":"string"},{"type":"null"}]}},"required":["status"],"additionalProperties":false}}},"required":["successCount","failureCount","results"],"additionalProperties":false},"GetCatalogCountries_Output":{"type":"object","properties":{"data":{"type":"array","description":"Catalog country codes available to your company","items":{"type":"string"}}},"required":["data"],"additionalProperties":false},"SearchCatalogProductsBody":{"type":"object","properties":{"search":{"description":"Substring match on the product NAME only (case-insensitive, not tokenized). Use it for a model name such as \"ThinkPad\" or \"MacBook Air\" — never for specifications, which it does not read: \"16 GB business laptop\" matches nothing.","type":"string"},"types":{"description":"Filter by product types (e.g. laptop, monitor)","type":"array","items":{"type":"string","enum":["laptop","tablet","smartphone","cable_adapter","charger","headset","hub","keyboard","laptop_case","monitor","mouse","other"]}},"brands":{"description":"Filter by brand names","type":"array","items":{"type":"string"}},"hasZTD":{"description":"Only return products that support zero-touch deployment","type":"boolean"},"hasStock":{"description":"Only return products with at least one supplier holding stock in the requested country","type":"boolean"},"specifications":{"description":"Filter on the product specifications, keyed by specification name. ram, storage (GB amounts), screenSize (whole inches) and processor (`BRAND|Family`) are canonical: pass the exact values the catalog filter-options endpoint returns for them, a value matches every product whose stored specification maps to it. operatingSystem, resolution, position, color and the other keys are matched as a case-insensitive PREFIX of the stored free-text specification. keyboardLayout takes the layout codes the filter-options endpoint returns and matches products with a variant (or a product-level layout) sold in the country, in stock when hasStock is set. Values inside one key are OR-ed, different keys are AND-ed: {\"ram\":[\"16\",\"32\"],\"operatingSystem\":[\"Windows 11 Pro\"]} returns 16 GB or 32 GB machines running Windows 11 Pro. There is no numeric comparison — express \"at least 16 GB\" by listing every option at or above 16.","type":"object","propertyNames":{"type":"string","enum":["cableLength","color","connectivity","inputConnectors","interfaces","keyboardLayout","notebookSupportedSizes","npu","operatingSystem","position","power","processor","ram","resolution","screenSize","storage"]},"additionalProperties":{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"}]}}},"page":{"default":1,"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},"take":{"default":100,"type":"integer","exclusiveMinimum":0,"maximum":100}}},"SearchCatalogProductsResult_Output":{"type":"object","properties":{"total":{"type":"integer","description":"Total number of products matching the search","minimum":-9007199254740991,"maximum":9007199254740991},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"brand":{"anyOf":[{"type":"string"},{"type":"null"}]},"images":{"description":"Product image URLs","type":"array","items":{"type":"string"}},"variations":{"description":"Variation dimensions available for this product (e.g. ram, storage)","type":"array","items":{"type":"string"}},"specifications":{"description":"Product specifications keyed by specification name","anyOf":[{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},{"type":"null"}]},"price":{"description":"Current price for the requested country","anyOf":[{"type":"object","properties":{"amount":{"description":"Price amount in the smallest currency unit (e.g. cents)","type":"number"},"currency":{"description":"ISO 4217 currency code","type":"string"}},"required":["amount","currency"],"additionalProperties":false},{"type":"null"}]},"isDiscontinued":{"description":"Whether the product is discontinued (deleted or no longer published)","type":"boolean"},"hasZTD":{"description":"Whether at least one variant supports zero-touch deployment","type":"boolean"},"hasFastDelivery":{"description":"Whether at least one variant supports fast delivery","type":"boolean"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","name","description","images","variations","isDiscontinued","hasZTD","hasFastDelivery","createdAt","updatedAt"],"additionalProperties":false}}},"required":["total","data"],"additionalProperties":false},"GetCatalogFilterOptions_Output":{"type":"object","properties":{"data":{"type":"object","properties":{"brands":{"type":"array","items":{"type":"string"}},"ram":{"description":"Canonical RAM amounts in GB","type":"array","items":{"type":"number"}},"storage":{"description":"Canonical storage amounts in GB (1024 = 1 TB)","type":"array","items":{"type":"number"}},"screenSize":{"description":"Screen diagonals rounded down to the inch","type":"array","items":{"type":"number"}},"processor":{"description":"Processor families as `BRAND|Family` (e.g. `INTEL|Core Ultra 7`)","type":"array","items":{"type":"string"}},"operatingSystem":{"type":"array","items":{"type":"string"}},"resolution":{"type":"array","items":{"type":"string"}},"position":{"type":"array","items":{"type":"string"}},"keyboardLayout":{"description":"Keyboard layout codes (e.g. `AZERTY_FR`, `QWERTY_US`) of the variants sold in the country","type":"array","items":{"type":"string"}}},"required":["brands","ram","storage","screenSize","processor","operatingSystem","resolution","position","keyboardLayout"],"additionalProperties":false}},"required":["data"],"additionalProperties":false},"GetCatalogProduct_Output":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"brand":{"anyOf":[{"type":"string"},{"type":"null"}]},"images":{"type":"array","description":"Product image URLs","items":{"type":"string"}},"variations":{"type":"array","description":"Variation dimensions available for this product (e.g. ram, storage)","items":{"type":"string"}},"specifications":{"description":"Product specifications keyed by specification name","anyOf":[{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},{"type":"null"}]},"price":{"description":"Current price for the requested country","anyOf":[{"type":"object","properties":{"amount":{"description":"Price amount in the smallest currency unit (e.g. cents)","type":"number"},"currency":{"description":"ISO 4217 currency code","type":"string"}},"required":["amount","currency"],"additionalProperties":false},{"type":"null"}]},"isDiscontinued":{"type":"boolean","description":"Whether the product is discontinued (deleted or no longer published)"},"hasZTD":{"type":"boolean","description":"Whether at least one variant supports zero-touch deployment"},"hasFastDelivery":{"type":"boolean","description":"Whether at least one variant supports fast delivery"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"countryCodes":{"type":"array","description":"Country codes where this product is available","items":{"type":"string"}},"variants":{"type":"array","description":"Variants with per-supplier stock information","items":{"type":"object","properties":{"id":{"type":"string"},"composition":{"description":"The variation values that define this variant (e.g. ram=16GB, storage=512GB)","type":"array","items":{"type":"object","properties":{"type":{"type":"string"},"value":{"type":"string"}},"required":["type","value"],"additionalProperties":false}},"reference":{"anyOf":[{"type":"string"},{"type":"null"}]},"stocks":{"type":"array","items":{"type":"object","properties":{"supplierId":{"description":"Supplier id — pass this as products[].supplierId when creating an order","type":"string"},"supplierName":{"type":"string"},"isZTD":{"description":"Whether this stock entry supports zero-touch deployment","type":"boolean"},"status":{"type":"string","enum":["out_of_stock","in_stock","low_stock","unknown","coming_soon"]},"quantity":{"description":"Available quantity, or null when unknown","anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"daysToDelivery":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]}},"required":["supplierId","supplierName","isZTD","status"],"additionalProperties":false}}},"required":["id","composition","stocks"],"additionalProperties":false}}},"required":["id","name","description","images","variations","isDiscontinued","hasZTD","hasFastDelivery","createdAt","updatedAt","countryCodes","variants"],"additionalProperties":false},"GetCatalogProductsBody":{"type":"object","properties":{"productIds":{"description":"Catalog product ids, as returned by searchCatalogProducts (e.g. product_<uuid>), at most 20 per call","minItems":1,"maxItems":20,"type":"array","items":{"type":"string","pattern":"^product_[0-9a-f-]{36}$"}}},"required":["productIds"]},"GetCatalogProducts_Output":{"type":"object","properties":{"data":{"type":"array","description":"The requested products in request order, each with its variants and per-supplier stock in the country. A product with no variant there has an empty `variants` list; a deleted or unpublished one has `isDiscontinued`.","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"brand":{"anyOf":[{"type":"string"},{"type":"null"}]},"images":{"description":"Product image URLs","type":"array","items":{"type":"string"}},"variations":{"description":"Variation dimensions available for this product (e.g. ram, storage)","type":"array","items":{"type":"string"}},"specifications":{"description":"Product specifications keyed by specification name","anyOf":[{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},{"type":"null"}]},"price":{"description":"Current price for the requested country","anyOf":[{"type":"object","properties":{"amount":{"description":"Price amount in the smallest currency unit (e.g. cents)","type":"number"},"currency":{"description":"ISO 4217 currency code","type":"string"}},"required":["amount","currency"],"additionalProperties":false},{"type":"null"}]},"isDiscontinued":{"description":"Whether the product is discontinued (deleted or no longer published)","type":"boolean"},"hasZTD":{"description":"Whether at least one variant supports zero-touch deployment","type":"boolean"},"hasFastDelivery":{"description":"Whether at least one variant supports fast delivery","type":"boolean"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"countryCodes":{"description":"Country codes where this product is available","type":"array","items":{"type":"string"}},"variants":{"description":"Variants with per-supplier stock information","type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"composition":{"description":"The variation values that define this variant (e.g. ram=16GB, storage=512GB)","type":"array","items":{"type":"object","properties":{"type":{"type":"string"},"value":{"type":"string"}},"required":["type","value"],"additionalProperties":false}},"reference":{"anyOf":[{"type":"string"},{"type":"null"}]},"stocks":{"type":"array","items":{"type":"object","properties":{"supplierId":{"description":"Supplier id — pass this as products[].supplierId when creating an order","type":"string"},"supplierName":{"type":"string"},"isZTD":{"description":"Whether this stock entry supports zero-touch deployment","type":"boolean"},"status":{"type":"string","enum":["out_of_stock","in_stock","low_stock","unknown","coming_soon"]},"quantity":{"description":"Available quantity, or null when unknown","anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"daysToDelivery":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]}},"required":["supplierId","supplierName","isZTD","status"],"additionalProperties":false}}},"required":["id","composition","stocks"],"additionalProperties":false}}},"required":["id","name","description","images","variations","isDiscontinued","hasZTD","hasFastDelivery","createdAt","updatedAt","countryCodes","variants"],"additionalProperties":false}},"notFound":{"type":"array","description":"Requested ids that match no catalog product","items":{"type":"string"}}},"required":["data","notFound"],"additionalProperties":false},"GetShippingCountries_Output":{"type":"object","properties":{"total":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"data":{"type":"array","items":{"type":"object","properties":{"countryCode":{"type":"string"},"status":{"type":"string","enum":["enabled","enabling","disabled"]}},"required":["countryCode","status"],"additionalProperties":false}}},"required":["total","data"],"additionalProperties":false},"GetCompanyAddresses_Output":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"contactName":{"anyOf":[{"type":"string"},{"type":"null"}]},"name":{"type":"string"},"street":{"type":"string"},"complement":{"anyOf":[{"type":"string"},{"type":"null"}]},"postalCode":{"type":"string"},"city":{"type":"string"},"country":{"anyOf":[{"type":"string"},{"type":"null"}]},"countryCode":{"anyOf":[{"type":"string"},{"type":"null"}]},"phone":{"anyOf":[{"type":"string"},{"type":"null"}]},"type":{"type":"string","enum":["HOME","WORK"]}},"required":["id","name","street","postalCode","city","type"],"additionalProperties":false}}},"required":["data"],"additionalProperties":false},"CatalogFavorites_Output":{"type":"object","properties":{"devices":{"type":"array","description":"Favorite device products, in the order they were curated","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"brand":{"anyOf":[{"type":"string"},{"type":"null"}]},"images":{"description":"Product image URLs","type":"array","items":{"type":"string"}},"variations":{"description":"Variation dimensions available for this product (e.g. ram, storage)","type":"array","items":{"type":"string"}},"specifications":{"description":"Product specifications keyed by specification name","anyOf":[{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},{"type":"null"}]},"price":{"description":"Current price for the requested country","anyOf":[{"type":"object","properties":{"amount":{"description":"Price amount in the smallest currency unit (e.g. cents)","type":"number"},"currency":{"description":"ISO 4217 currency code","type":"string"}},"required":["amount","currency"],"additionalProperties":false},{"type":"null"}]},"isDiscontinued":{"description":"Whether the product is discontinued (deleted or no longer published)","type":"boolean"},"hasZTD":{"description":"Whether at least one variant supports zero-touch deployment","type":"boolean"},"hasFastDelivery":{"description":"Whether at least one variant supports fast delivery","type":"boolean"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","name","description","images","variations","isDiscontinued","hasZTD","hasFastDelivery","createdAt","updatedAt"],"additionalProperties":false}},"accessories":{"type":"array","description":"Favorite accessory products, in the order they were curated","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"brand":{"anyOf":[{"type":"string"},{"type":"null"}]},"images":{"description":"Product image URLs","type":"array","items":{"type":"string"}},"variations":{"description":"Variation dimensions available for this product (e.g. ram, storage)","type":"array","items":{"type":"string"}},"specifications":{"description":"Product specifications keyed by specification name","anyOf":[{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},{"type":"null"}]},"price":{"description":"Current price for the requested country","anyOf":[{"type":"object","properties":{"amount":{"description":"Price amount in the smallest currency unit (e.g. cents)","type":"number"},"currency":{"description":"ISO 4217 currency code","type":"string"}},"required":["amount","currency"],"additionalProperties":false},{"type":"null"}]},"isDiscontinued":{"description":"Whether the product is discontinued (deleted or no longer published)","type":"boolean"},"hasZTD":{"description":"Whether at least one variant supports zero-touch deployment","type":"boolean"},"hasFastDelivery":{"description":"Whether at least one variant supports fast delivery","type":"boolean"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","name","description","images","variations","isDiscontinued","hasZTD","hasFastDelivery","createdAt","updatedAt"],"additionalProperties":false}}},"required":["devices","accessories"],"additionalProperties":false},"GetShipments_Output":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"employeeId":{"anyOf":[{"type":"string"},{"type":"null"}]},"reference":{"type":"string"},"status":{"type":"string","enum":["PLACED","CONFIRMED","UNKNOWN","PRE_TRANSIT","IN_TRANSIT","OUT_FOR_DELIVERY","DELIVERED","AVAILABLE_FOR_PICKUP","RETURN_TO_SENDER","FAILURE","ERROR","CLOSED","CANCELED"]},"reason":{"anyOf":[{"type":"string","enum":["ONBOARDING","OFFBOARDING","RENEWAL","SEND_TO_EMPLOYEE","SEND_TO_OFFICE","RECYCLE","REPAIR","RESELL","OTHER","BOX"]},{"type":"null"}]},"trackerStatus":{"anyOf":[{"type":"string","enum":["unknown","pre_transit","in_transit","out_for_delivery","delivered","available_for_pickup","return_to_sender","failure","cancelled","error"]},{"type":"null"}]},"estimatedDeliveryDate":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"box":{"anyOf":[{"type":"object","properties":{"status":{"type":"string","enum":["BOX_ORDERED","BOX_SHIPPED","BOX_DELIVERED"]},"trackingCode":{"anyOf":[{"type":"string"},{"type":"null"}]},"trackingLink":{"anyOf":[{"type":"string"},{"type":"null"}]},"estimatedDeliveryDate":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]}},"required":["status"],"additionalProperties":false},{"type":"null"}]},"content":{"type":"array","items":{"type":"object","properties":{"id":{"anyOf":[{"type":"string"},{"type":"null"}]},"name":{"type":"string"},"type":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["name"],"additionalProperties":false}},"previewFromAddress":{"anyOf":[{"type":"object","properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}]},"countryCode":{"anyOf":[{"type":"string"},{"type":"null"}]}},"additionalProperties":false},{"type":"null"}]},"previewToAddress":{"anyOf":[{"type":"object","properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}]},"countryCode":{"anyOf":[{"type":"string"},{"type":"null"}]}},"additionalProperties":false},{"type":"null"}]}},"required":["id","reference","status","createdAt","content"],"additionalProperties":false}},"pagination":{"type":"object","properties":{"totalElements":{"type":"integer","minimum":0,"maximum":9007199254740991},"totalPages":{"type":"integer","minimum":0,"maximum":9007199254740991},"page":{"type":"integer","minimum":1,"maximum":9007199254740991},"perPage":{"type":"integer","minimum":1,"maximum":100}},"required":["totalElements","totalPages","page","perPage"],"additionalProperties":false}},"required":["data","pagination"],"additionalProperties":false},"GetShipment_Output":{"type":"object","properties":{"id":{"type":"string"},"employeeId":{"anyOf":[{"type":"string"},{"type":"null"}]},"reference":{"type":"string"},"status":{"type":"string","enum":["PLACED","CONFIRMED","UNKNOWN","PRE_TRANSIT","IN_TRANSIT","OUT_FOR_DELIVERY","DELIVERED","AVAILABLE_FOR_PICKUP","RETURN_TO_SENDER","FAILURE","ERROR","CLOSED","CANCELED"]},"reason":{"anyOf":[{"type":"string","enum":["ONBOARDING","OFFBOARDING","RENEWAL","SEND_TO_EMPLOYEE","SEND_TO_OFFICE","RECYCLE","REPAIR","RESELL","OTHER","BOX"]},{"type":"null"}]},"trackerStatus":{"anyOf":[{"type":"string","enum":["unknown","pre_transit","in_transit","out_for_delivery","delivered","available_for_pickup","return_to_sender","failure","cancelled","error"]},{"type":"null"}]},"estimatedDeliveryDate":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"box":{"anyOf":[{"type":"object","properties":{"status":{"type":"string","enum":["BOX_ORDERED","BOX_SHIPPED","BOX_DELIVERED"]},"trackingCode":{"anyOf":[{"type":"string"},{"type":"null"}]},"trackingLink":{"anyOf":[{"type":"string"},{"type":"null"}]},"estimatedDeliveryDate":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]}},"required":["status"],"additionalProperties":false},{"type":"null"}]},"content":{"type":"array","items":{"type":"object","properties":{"id":{"anyOf":[{"type":"string"},{"type":"null"}]},"name":{"type":"string"},"type":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["name"],"additionalProperties":false}},"previewFromAddress":{"anyOf":[{"type":"object","properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}]},"countryCode":{"anyOf":[{"type":"string"},{"type":"null"}]}},"additionalProperties":false},{"type":"null"}]},"previewToAddress":{"anyOf":[{"type":"object","properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}]},"countryCode":{"anyOf":[{"type":"string"},{"type":"null"}]}},"additionalProperties":false},{"type":"null"}]}},"required":["id","reference","status","createdAt","content"],"additionalProperties":false},"CreateShipmentBody":{"type":"object","properties":{"fromAddress":{"type":"object","properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}]},"contactName":{"anyOf":[{"type":"string"},{"type":"null"}]},"phone":{"anyOf":[{"type":"string"},{"type":"null"}]},"street":{"type":"string","minLength":1},"complement":{"anyOf":[{"type":"string"},{"type":"null"}]},"postalCode":{"type":"string","minLength":1},"city":{"type":"string","minLength":1},"country":{"anyOf":[{"type":"string"},{"type":"null"}]},"countryCode":{"anyOf":[{"type":"string"},{"type":"null"}]},"type":{"anyOf":[{"type":"string","enum":["HOME","WORK"]},{"type":"null"}]}},"required":["street","postalCode","city"]},"toAddress":{"type":"object","properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}]},"contactName":{"anyOf":[{"type":"string"},{"type":"null"}]},"phone":{"anyOf":[{"type":"string"},{"type":"null"}]},"street":{"type":"string","minLength":1},"complement":{"anyOf":[{"type":"string"},{"type":"null"}]},"postalCode":{"type":"string","minLength":1},"city":{"type":"string","minLength":1},"country":{"anyOf":[{"type":"string"},{"type":"null"}]},"countryCode":{"anyOf":[{"type":"string"},{"type":"null"}]},"type":{"anyOf":[{"type":"string","enum":["HOME","WORK"]},{"type":"null"}]}},"required":["street","postalCode","city"]},"parcel":{"type":"object","properties":{"weight":{"type":"integer","minimum":100,"maximum":20000},"length":{"type":"integer","minimum":10,"maximum":1000},"width":{"type":"integer","minimum":10,"maximum":1000},"height":{"type":"integer","minimum":10,"maximum":1000}},"required":["weight","length","width","height"]},"hasInsurance":{"type":"boolean"},"value":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},"content":{"type":"array","items":{"type":"object","properties":{"id":{"anyOf":[{"type":"string"},{"type":"null"}]},"name":{"type":"string"},"type":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["name"]}},"billingProfileId":{"type":"string","minLength":1},"reason":{"anyOf":[{"type":"string","enum":["ONBOARDING","OFFBOARDING","RENEWAL","SEND_TO_EMPLOYEE","SEND_TO_OFFICE","RECYCLE","REPAIR","RESELL","OTHER","BOX"]},{"type":"null"}]},"comment":{"anyOf":[{"type":"string"},{"type":"null"}]},"notificationEmails":{"default":[],"type":"array","items":{"type":"string"}},"createBoxShipment":{"type":"boolean"}},"required":["fromAddress","toAddress","parcel","hasInsurance","value","content","billingProfileId"]},"ShipmentWriteResult_Output":{"type":"object","properties":{"success":{"type":"boolean","const":true}},"required":["success"],"additionalProperties":false},"ListKnowledgeBaseItemsResponseDto_Output":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"status":{"description":"Publication state. \"unpublished\": never published (or hidden). \"pending-changes\": the draft has edits not yet published. \"published\": the draft matches the published text.","type":"string","enum":["unpublished","pending-changes","published"]},"draft":{"description":"The editable draft. This is the text updateKnowledgeBaseItemDraft writes.","type":"object","properties":{"name":{"description":"The item name.","type":"string"},"description":{"description":"A short description of what the item is for.","type":"string"},"content":{"description":"The Markdown body of the item (frontmatter name + description, then content).","type":"string"}},"required":["name","description","content"],"additionalProperties":false},"published":{"description":"The published text the AI agent sees at runtime, or null if never published. Diff it against the draft to surface pending edits.","anyOf":[{"type":"object","properties":{"name":{"description":"The item name.","type":"string"},"description":{"description":"A short description of what the item is for.","type":"string"},"content":{"description":"The Markdown body of the item (frontmatter name + description, then content).","type":"string"}},"required":["name","description","content"],"additionalProperties":false},{"type":"null"}]}},"required":["id","status","draft","published"],"additionalProperties":false}}},"required":["items"],"additionalProperties":false},"GetKnowledgeBaseItemResponseDto_Output":{"type":"object","properties":{"item":{"type":"object","properties":{"id":{"type":"string"},"status":{"description":"Publication state. \"unpublished\": never published (or hidden). \"pending-changes\": the draft has edits not yet published. \"published\": the draft matches the published text.","type":"string","enum":["unpublished","pending-changes","published"]},"draft":{"description":"The editable draft. This is the text updateKnowledgeBaseItemDraft writes.","type":"object","properties":{"name":{"description":"The item name.","type":"string"},"description":{"description":"A short description of what the item is for.","type":"string"},"content":{"description":"The Markdown body of the item (frontmatter name + description, then content).","type":"string"}},"required":["name","description","content"],"additionalProperties":false},"published":{"description":"The published text the AI agent sees at runtime, or null if never published. Diff it against the draft to surface pending edits.","anyOf":[{"type":"object","properties":{"name":{"description":"The item name.","type":"string"},"description":{"description":"A short description of what the item is for.","type":"string"},"content":{"description":"The Markdown body of the item (frontmatter name + description, then content).","type":"string"}},"required":["name","description","content"],"additionalProperties":false},{"type":"null"}]}},"required":["id","status","draft","published"],"additionalProperties":false}},"required":["item"],"additionalProperties":false},"GetOnboardings_Output":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"employeeId":{"anyOf":[{"type":"string"},{"type":"null"}]},"ticketId":{"anyOf":[{"type":"string"},{"type":"null"}]},"status":{"type":"string","enum":["PENDING","SCHEDULED","IN_PROGRESS","CLOSED","CANCELED"]},"stepModel":{"description":"How the onboarding holds its steps: ACTIONS (the onboarding steps and their plain tasks) or INTENTS (typed tasks under its ticket, run through the intent tools such as `executeEmployeeCreationIntent`). Null while it has neither a ticket nor a step, and for an onboarding run by the agent.","anyOf":[{"type":"string","enum":["ACTIONS","INTENTS"]},{"type":"null"}]},"stepProgress":{"description":"How many of its steps are through, out of how many: on ACTIONS its steps done, scheduled or skipped; otherwise the typed tasks of its ticket completed or cancelled. Null while it has no step.","anyOf":[{"type":"object","properties":{"done":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"total":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["done","total"],"additionalProperties":false},{"type":"null"}]},"source":{"type":"string","enum":["COCKPIT","MERGE","KOMBO","API"]},"suggestedEmail":{"anyOf":[{"type":"string"},{"type":"null"}]},"startDate":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"hrRecords":{"description":"HR records from the connected HRIS (Kombo) for this onboarding","type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"remoteId":{"anyOf":[{"type":"string"},{"type":"null"}]},"firstName":{"anyOf":[{"type":"string"},{"type":"null"}]},"lastName":{"anyOf":[{"type":"string"},{"type":"null"}]},"email":{"anyOf":[{"type":"string"},{"type":"null"}]},"personalEmail":{"anyOf":[{"type":"string"},{"type":"null"}]},"phone":{"anyOf":[{"type":"string"},{"type":"null"}]},"startDate":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"terminationDate":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]}},"required":["id"],"additionalProperties":false}},"hire":{"description":"The hire an admin added by hand in the cockpit short form; their personal email and note are on `getOnboarding`","anyOf":[{"type":"object","properties":{"firstName":{"type":"string"},"lastName":{"type":"string"},"jobTitle":{"anyOf":[{"type":"string"},{"type":"null"}]},"teamId":{"description":"The Primo team the note names, when exactly one matches","anyOf":[{"type":"string"},{"type":"null"}]},"teamName":{"anyOf":[{"type":"string"},{"type":"null"}]},"managerId":{"description":"The Primo employee the note names as manager, when exactly one matches","anyOf":[{"type":"string"},{"type":"null"}]},"managerName":{"anyOf":[{"type":"string"},{"type":"null"}]},"workLocationId":{"description":"The Primo work location the note names, when exactly one matches","anyOf":[{"type":"string"},{"type":"null"}]},"workLocationName":{"anyOf":[{"type":"string"},{"type":"null"}]},"workMode":{"anyOf":[{"type":"string","enum":["REMOTE","ON_SITE","HYBRID"]},{"type":"null"}]},"city":{"anyOf":[{"type":"string"},{"type":"null"}]},"agentNotes":{"description":"What the note left ambiguous or could not file in a field, to ask or act on","type":"array","items":{"type":"string"}}},"required":["firstName","lastName","agentNotes"],"additionalProperties":false},{"type":"null"}]}},"required":["id","status","source","createdAt","hrRecords"],"additionalProperties":false}},"pagination":{"type":"object","properties":{"totalElements":{"type":"integer","minimum":0,"maximum":9007199254740991},"totalPages":{"type":"integer","minimum":0,"maximum":9007199254740991},"page":{"type":"integer","minimum":1,"maximum":9007199254740991},"perPage":{"type":"integer","minimum":1,"maximum":100}},"required":["totalElements","totalPages","page","perPage"],"additionalProperties":false}},"required":["data","pagination"],"additionalProperties":false},"GetOnboardingSettings_Output":{"type":"object","properties":{"emailIncluded":{"type":"boolean","description":"Whether the professional email step is part of every onboarding."},"provisioningIncluded":{"type":"boolean","description":"Whether the SaaS provisioning step is part of every onboarding."},"equipmentIncluded":{"type":"boolean","description":"Whether the equipment step is part of every onboarding."},"equipmentHandledByAi":{"type":"boolean","description":"Whether the Primo AI agent drives the equipment step instead of a human owner."},"addPrimoAiAgent":{"type":"boolean","description":"Whether the Primo AI agent is put on every onboarding ticket."},"equipmentMdmEnrollment":{"type":"boolean","description":"Whether ordered devices are enrolled in MDM automatically."},"saasApplicationSuggestions":{"type":"boolean","description":"Whether Primo suggests SaaS applications for the joiner."},"emailCreationChoice":{"type":"string","description":"CREATE provisions a new address, EXISTING reuses the one the HRIS carries.","enum":["CREATE","EXISTING"]},"emailExistingAddressHandling":{"anyOf":[{"type":"string","enum":["USE_AS_IS","MANUAL_CONFIRMATION"]},{"type":"null"}]},"emailScheduling":{"anyOf":[{"type":"object","properties":{"numberDaysBefore":{"description":"Days before the start date the step runs on. 0 means the start date.","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"time":{"description":"Time of day the step runs at, as \"HH:mm\".","type":"string"}},"required":["numberDaysBefore","time"],"additionalProperties":false},{"type":"null"}]},"provisioningScheduling":{"anyOf":[{"type":"object","properties":{"numberDaysBefore":{"description":"Days before the start date the step runs on. 0 means the start date.","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"time":{"description":"Time of day the step runs at, as \"HH:mm\".","type":"string"}},"required":["numberDaysBefore","time"],"additionalProperties":false},{"type":"null"}]},"equipmentScheduling":{"anyOf":[{"type":"object","properties":{"numberDaysBefore":{"description":"Days before the start date the step runs on. 0 means the start date.","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"time":{"description":"Time of day the step runs at, as \"HH:mm\".","type":"string"}},"required":["numberDaysBefore","time"],"additionalProperties":false},{"type":"null"}]},"automaticProcessingActions":{"type":"array","description":"Steps Primo executes without waiting for an admin to validate them.","items":{"type":"string","enum":["EMPLOYEE_INFORMATION","EMPLOYEE_EMAIL","EMPLOYEE_PROVISIONING","EMPLOYEE_EQUIPMENT"]}},"defaultTaskOwner":{"description":"Assignee of the onboarding ticket and of every step with no owner of its own. Null means unassigned.","anyOf":[{"type":"object","properties":{"type":{"type":"string","enum":["EMPLOYEE","EXTERNAL_ADMIN"]},"employeeId":{"description":"Primo employee id. Required when `type` is EMPLOYEE — get it from `getEmployees`.","anyOf":[{"type":"string"},{"type":"null"}]},"userId":{"description":"Clerk user id of an admin without an employee record. Required when `type` is EXTERNAL_ADMIN.","anyOf":[{"type":"string"},{"type":"null"}]}},"required":["type"],"additionalProperties":false},{"type":"null"}]},"defaultTaskPriority":{"anyOf":[{"type":"string","enum":["LOW","MEDIUM","HIGH"]},{"type":"null"}]},"defaultTaskSubscribers":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","enum":["EMPLOYEE","EXTERNAL_ADMIN"]},"employeeId":{"description":"Primo employee id. Required when `type` is EMPLOYEE — get it from `getEmployees`.","anyOf":[{"type":"string"},{"type":"null"}]},"userId":{"description":"Clerk user id of an admin without an employee record. Required when `type` is EXTERNAL_ADMIN.","anyOf":[{"type":"string"},{"type":"null"}]}},"required":["type"],"additionalProperties":false}},"taskSettings":{"type":"array","description":"Per-step overrides of owner, due date and scheduling.","items":{"type":"object","properties":{"actionType":{"type":"string","enum":["EMPLOYEE_INFORMATION","EMPLOYEE_EMAIL","EMPLOYEE_PROVISIONING","EMPLOYEE_EQUIPMENT"]},"owner":{"description":"Assignee of that step task. Falls back to `defaultTaskOwner`.","anyOf":[{"type":"object","properties":{"type":{"type":"string","enum":["EMPLOYEE","EXTERNAL_ADMIN"]},"employeeId":{"description":"Primo employee id. Required when `type` is EMPLOYEE — get it from `getEmployees`.","anyOf":[{"type":"string"},{"type":"null"}]},"userId":{"description":"Clerk user id of an admin without an employee record. Required when `type` is EXTERNAL_ADMIN.","anyOf":[{"type":"string"},{"type":"null"}]}},"required":["type"],"additionalProperties":false},{"type":"null"}]},"dueDateNumberDaysBefore":{"description":"Days before the start date the task is due.","anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"scheduling":{"anyOf":[{"type":"object","properties":{"numberDaysBefore":{"description":"Days before the start date the step runs on. 0 means the start date.","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"time":{"description":"Time of day the step runs at, as \"HH:mm\".","type":"string"}},"required":["numberDaysBefore","time"],"additionalProperties":false},{"type":"null"}]}},"required":["actionType"],"additionalProperties":false}},"onboardingTicketCreation":{"type":"string","description":"When a hire detected in the HRIS gets its onboarding ticket: 30, 45 or 60 days before the start date (a hire detected later gets it right away), as soon as the HRIS shows the hire, or never automatically (MANUAL_ONLY, the ticket is then created by hand). Hires without a start date or starting in the past never get one automatically.","enum":["BEFORE_START_30_DAYS","BEFORE_START_45_DAYS","BEFORE_START_60_DAYS","ON_HRIS_DETECTION","MANUAL_ONLY"]}},"required":["emailIncluded","provisioningIncluded","equipmentIncluded","equipmentHandledByAi","addPrimoAiAgent","equipmentMdmEnrollment","saasApplicationSuggestions","emailCreationChoice","automaticProcessingActions","defaultTaskSubscribers","taskSettings","onboardingTicketCreation"],"additionalProperties":false},"UpdateOnboardingSettingsBody":{"type":"object","properties":{"emailIncluded":{"description":"Whether the professional email step is part of every onboarding.","type":"boolean"},"provisioningIncluded":{"description":"Whether the SaaS provisioning step is part of every onboarding.","type":"boolean"},"equipmentIncluded":{"description":"Whether the equipment step is part of every onboarding.","type":"boolean"},"equipmentHandledByAi":{"description":"Whether the Primo AI agent drives the equipment step instead of a human owner.","type":"boolean"},"addPrimoAiAgent":{"description":"Whether the Primo AI agent is put on every onboarding ticket.","type":"boolean"},"equipmentMdmEnrollment":{"description":"Whether ordered devices are enrolled in MDM automatically.","type":"boolean"},"saasApplicationSuggestions":{"description":"Whether Primo suggests SaaS applications for the joiner.","type":"boolean"},"emailCreationChoice":{"description":"CREATE provisions a new address, EXISTING reuses the one the HRIS carries.","type":"string","enum":["CREATE","EXISTING"]},"emailExistingAddressHandling":{"anyOf":[{"type":"string","enum":["USE_AS_IS","MANUAL_CONFIRMATION"]},{"type":"null"}]},"emailScheduling":{"anyOf":[{"type":"object","properties":{"numberDaysBefore":{"description":"Days before the start date the step runs on. 0 means the start date.","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"time":{"description":"Time of day the step runs at, as \"HH:mm\".","type":"string"}},"required":["numberDaysBefore","time"]},{"type":"null"}]},"provisioningScheduling":{"anyOf":[{"type":"object","properties":{"numberDaysBefore":{"description":"Days before the start date the step runs on. 0 means the start date.","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"time":{"description":"Time of day the step runs at, as \"HH:mm\".","type":"string"}},"required":["numberDaysBefore","time"]},{"type":"null"}]},"equipmentScheduling":{"anyOf":[{"type":"object","properties":{"numberDaysBefore":{"description":"Days before the start date the step runs on. 0 means the start date.","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"time":{"description":"Time of day the step runs at, as \"HH:mm\".","type":"string"}},"required":["numberDaysBefore","time"]},{"type":"null"}]},"automaticProcessingActions":{"description":"Steps Primo executes without waiting for an admin to validate them.","type":"array","items":{"type":"string","enum":["EMPLOYEE_INFORMATION","EMPLOYEE_EMAIL","EMPLOYEE_PROVISIONING","EMPLOYEE_EQUIPMENT"]}},"defaultTaskOwner":{"description":"Assignee of the onboarding ticket and of every step with no owner of its own. Null means unassigned.","anyOf":[{"type":"object","properties":{"type":{"type":"string","enum":["EMPLOYEE","EXTERNAL_ADMIN"]},"employeeId":{"description":"Primo employee id. Required when `type` is EMPLOYEE — get it from `getEmployees`.","anyOf":[{"type":"string"},{"type":"null"}]},"userId":{"description":"Clerk user id of an admin without an employee record. Required when `type` is EXTERNAL_ADMIN.","anyOf":[{"type":"string"},{"type":"null"}]}},"required":["type"]},{"type":"null"}]},"defaultTaskPriority":{"anyOf":[{"type":"string","enum":["LOW","MEDIUM","HIGH"]},{"type":"null"}]},"defaultTaskSubscribers":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","enum":["EMPLOYEE","EXTERNAL_ADMIN"]},"employeeId":{"description":"Primo employee id. Required when `type` is EMPLOYEE — get it from `getEmployees`.","anyOf":[{"type":"string"},{"type":"null"}]},"userId":{"description":"Clerk user id of an admin without an employee record. Required when `type` is EXTERNAL_ADMIN.","anyOf":[{"type":"string"},{"type":"null"}]}},"required":["type"]}},"taskSettings":{"description":"Per-step overrides of owner, due date and scheduling.","type":"array","items":{"type":"object","properties":{"actionType":{"type":"string","enum":["EMPLOYEE_INFORMATION","EMPLOYEE_EMAIL","EMPLOYEE_PROVISIONING","EMPLOYEE_EQUIPMENT"]},"owner":{"description":"Assignee of that step task. Falls back to `defaultTaskOwner`.","anyOf":[{"type":"object","properties":{"type":{"type":"string","enum":["EMPLOYEE","EXTERNAL_ADMIN"]},"employeeId":{"description":"Primo employee id. Required when `type` is EMPLOYEE — get it from `getEmployees`.","anyOf":[{"type":"string"},{"type":"null"}]},"userId":{"description":"Clerk user id of an admin without an employee record. Required when `type` is EXTERNAL_ADMIN.","anyOf":[{"type":"string"},{"type":"null"}]}},"required":["type"]},{"type":"null"}]},"dueDateNumberDaysBefore":{"description":"Days before the start date the task is due.","anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"scheduling":{"anyOf":[{"type":"object","properties":{"numberDaysBefore":{"description":"Days before the start date the step runs on. 0 means the start date.","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"time":{"description":"Time of day the step runs at, as \"HH:mm\".","type":"string"}},"required":["numberDaysBefore","time"]},{"type":"null"}]}},"required":["actionType"]}},"onboardingTicketCreation":{"description":"When a hire detected in the HRIS gets its onboarding ticket: 30, 45 or 60 days before the start date (a hire detected later gets it right away), as soon as the HRIS shows the hire, or never automatically (MANUAL_ONLY, the ticket is then created by hand). Hires without a start date or starting in the past never get one automatically.","type":"string","enum":["BEFORE_START_30_DAYS","BEFORE_START_45_DAYS","BEFORE_START_60_DAYS","ON_HRIS_DETECTION","MANUAL_ONLY"]}}},"CreateOnboardingBody":{"type":"object","properties":{"employeeId":{"description":"Primo employee id of the joiner. Get it from `getEmployees` or `createEmployee`.","type":"string","pattern":"^[a-f\\d]{24}$"},"startDate":{"description":"First day of the joiner (ISO 8601), past or future. Omit to use the start date already on the employee record; when sent, the employee record is updated to match.","anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]}},"required":["employeeId"]},"GetOnboarding_Output":{"type":"object","properties":{"id":{"type":"string"},"employeeId":{"anyOf":[{"type":"string"},{"type":"null"}]},"ticketId":{"anyOf":[{"type":"string"},{"type":"null"}]},"status":{"type":"string","enum":["PENDING","SCHEDULED","IN_PROGRESS","CLOSED","CANCELED"]},"stepModel":{"description":"How the onboarding holds its steps: ACTIONS (the onboarding steps and their plain tasks) or INTENTS (typed tasks under its ticket, run through the intent tools such as `executeEmployeeCreationIntent`). Null while it has neither a ticket nor a step, and for an onboarding run by the agent.","anyOf":[{"type":"string","enum":["ACTIONS","INTENTS"]},{"type":"null"}]},"stepProgress":{"description":"How many of its steps are through, out of how many: on ACTIONS its steps done, scheduled or skipped; otherwise the typed tasks of its ticket completed or cancelled. Null while it has no step.","anyOf":[{"type":"object","properties":{"done":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"total":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["done","total"],"additionalProperties":false},{"type":"null"}]},"source":{"type":"string","enum":["COCKPIT","MERGE","KOMBO","API"]},"suggestedEmail":{"anyOf":[{"type":"string"},{"type":"null"}]},"startDate":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"hrRecords":{"type":"array","description":"HR records from the connected HRIS (Kombo) for this onboarding","items":{"type":"object","properties":{"id":{"type":"string"},"remoteId":{"anyOf":[{"type":"string"},{"type":"null"}]},"firstName":{"anyOf":[{"type":"string"},{"type":"null"}]},"lastName":{"anyOf":[{"type":"string"},{"type":"null"}]},"email":{"anyOf":[{"type":"string"},{"type":"null"}]},"personalEmail":{"anyOf":[{"type":"string"},{"type":"null"}]},"phone":{"anyOf":[{"type":"string"},{"type":"null"}]},"startDate":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"terminationDate":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]}},"required":["id"],"additionalProperties":false}},"hire":{"description":"The hire an admin added by hand in the cockpit short form, before they are an employee in Primo","anyOf":[{"type":"object","properties":{"firstName":{"type":"string"},"lastName":{"type":"string"},"personalEmail":{"description":"Where to reach the hire until their work mailbox exists","type":"string"},"rawText":{"description":"What the admin wrote about the hire, in their own words","anyOf":[{"type":"string"},{"type":"null"}]},"jobTitle":{"anyOf":[{"type":"string"},{"type":"null"}]},"teamId":{"description":"The Primo team the note names, when exactly one matches","anyOf":[{"type":"string"},{"type":"null"}]},"teamName":{"anyOf":[{"type":"string"},{"type":"null"}]},"managerId":{"description":"The Primo employee the note names as manager, when exactly one matches","anyOf":[{"type":"string"},{"type":"null"}]},"managerName":{"anyOf":[{"type":"string"},{"type":"null"}]},"workLocationId":{"description":"The Primo work location the note names, when exactly one matches","anyOf":[{"type":"string"},{"type":"null"}]},"workLocationName":{"anyOf":[{"type":"string"},{"type":"null"}]},"workMode":{"anyOf":[{"type":"string","enum":["REMOTE","ON_SITE","HYBRID"]},{"type":"null"}]},"city":{"anyOf":[{"type":"string"},{"type":"null"}]},"agentNotes":{"description":"What the note left ambiguous or could not file in a field, to ask or act on","type":"array","items":{"type":"string"}}},"required":["firstName","lastName","personalEmail","agentNotes"],"additionalProperties":false},{"type":"null"}]}},"required":["id","status","source","createdAt","hrRecords"],"additionalProperties":false},"CompleteOnboardingsBody":{"type":"object","properties":{"onboardingIds":{"description":"IDs of the onboardings to complete (1-10, unique). Best-effort and independent: inspect the per-id `results` — the HTTP status is 200 even when some items fail.","minItems":1,"maxItems":10,"type":"array","items":{"type":"string"}}},"required":["onboardingIds"]},"CompleteOnboardingsResult_Output":{"type":"object","properties":{"successCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"failureCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"results":{"type":"array","description":"Per-onboarding outcome, in the same order as the input.","items":{"type":"object","properties":{"onboardingId":{"type":"string"},"status":{"type":"string","enum":["ok","error"]},"errorCode":{"description":"Machine-readable error code when status is \"error\".","anyOf":[{"type":"string"},{"type":"null"}]}},"required":["onboardingId","status"],"additionalProperties":false}}},"required":["successCount","failureCount","results"],"additionalProperties":false},"IgnoreOnboardingsBody":{"type":"object","properties":{"onboardingIds":{"description":"IDs of the onboardings to ignore (1-10, unique). Best-effort and independent: inspect the per-id `results` — the HTTP status is 200 even when some items fail.","minItems":1,"maxItems":10,"type":"array","items":{"type":"string"}}},"required":["onboardingIds"]},"IgnoreOnboardingsResult_Output":{"type":"object","properties":{"successCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"failureCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"results":{"type":"array","description":"Per-onboarding outcome, in the same order as the input.","items":{"type":"object","properties":{"onboardingId":{"type":"string"},"status":{"type":"string","enum":["ok","error"]},"errorCode":{"description":"Machine-readable error code when status is \"error\".","anyOf":[{"type":"string"},{"type":"null"}]}},"required":["onboardingId","status"],"additionalProperties":false}}},"required":["successCount","failureCount","results"],"additionalProperties":false},"ExecuteOnboardingEquipmentBody":{"type":"object","properties":{"order":{"description":"Catalog order to place. Omit when nothing is purchased.","type":"object","properties":{"countryCode":{"description":"Catalog country code (lowercase ISO 3166-1 alpha-2)","type":"string","enum":["af","al","dz","ad","ao","ag","ar","am","au","at","az","bs","bh","bd","bb","by","be","bz","bj","bt","bo","ba","bw","br","bn","bg","bf","bi","cv","kh","cm","ca","cf","td","cl","cn","co","km","cg","cr","hr","cu","cy","cz","cd","dk","dj","dm","do","ec","eg","sv","gq","er","ee","sz","et","fj","fi","fr","ga","gm","ge","de","gh","gr","gd","gt","gn","gw","gy","ht","hn","hu","is","in","id","ir","iq","ie","il","it","jm","jp","jo","kz","ke","ki","kw","kg","la","lv","lb","ls","lr","ly","li","lt","lu","mg","mw","my","mv","ml","mt","mh","mr","mu","mx","fm","md","mc","mn","me","ma","mz","mm","na","nr","np","nl","nz","ni","ne","ng","kp","mk","no","om","pk","pw","pa","pg","py","pe","ph","pl","pt","qa","ro","ru","rw","kn","lc","vc","ws","sm","st","sa","sn","rs","sc","sl","sg","sk","si","sb","so","za","kr","ss","es","lk","sd","sr","se","ch","sy","tw","tj","tz","th","tl","tg","to","tt","tn","tr","tm","tv","ug","ua","ae","gb","us","uy","uz","vu","va","ve","vn","ye","zm","zw"]},"products":{"minItems":1,"type":"array","items":{"type":"object","properties":{"id":{"description":"Catalog product id","type":"string"},"variantId":{"description":"Selected product variant id","type":"string"},"supplierId":{"description":"Supplier id for this product","type":"string"},"hasZTD":{"type":"boolean"},"configuration":{"type":"object","properties":{"enableZTD":{"type":"boolean"},"enableACE":{"type":"boolean"}},"required":["enableZTD","enableACE"]}},"required":["id","variantId","supplierId","configuration"]}},"shippingAddressType":{"description":"Where the address comes from. HOME also back-fills the employee record when it has no address yet, so send it whenever the address is the employee's own.","anyOf":[{"type":"string","enum":["OFFICE","HOME","NEW"]},{"type":"null"}]},"shippingAddress":{"description":"Delivery address. Take it from `getCompanyAddresses` or from the employee record — never compose one.","type":"object","properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}]},"contactName":{"anyOf":[{"type":"string"},{"type":"null"}]},"phone":{"description":"Send null when no phone number is known.","anyOf":[{"type":"string"},{"type":"null"}]},"street":{"type":"string","minLength":1},"complement":{"anyOf":[{"type":"string"},{"type":"null"}]},"postalCode":{"type":"string","minLength":1},"city":{"type":"string","minLength":1},"country":{"anyOf":[{"type":"string"},{"type":"null"}]},"countryCode":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["phone","street","postalCode","city"]},"billingProfileId":{"description":"An eligible company billing profile id","anyOf":[{"type":"string","minLength":1},{"type":"null"}]},"notificationEmails":{"type":"array","items":{"type":"string"}},"internalComment":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}]},"companyComment":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}]},"appleCareEnterprise":{"anyOf":[{"type":"string"},{"type":"null"}]},"companyPurchaseNumber":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["countryCode","products","shippingAddress"]},"assignedFromInventory":{"description":"Devices and accessories taken from existing stock and assigned to the employee.","type":"object","properties":{"deviceIds":{"type":"array","items":{"type":"string"}},"accessoryIds":{"type":"array","items":{"type":"string"}}},"required":["deviceIds","accessoryIds"]},"automaticEnrollment":{"description":"Leave unset to keep the onboarding current setting.","type":"boolean"}}},"ExecuteOnboardingEquipmentResult_Output":{"type":"object","properties":{"onboarding":{"type":"object","properties":{"id":{"type":"string"},"employeeId":{"anyOf":[{"type":"string"},{"type":"null"}]},"ticketId":{"anyOf":[{"type":"string"},{"type":"null"}]},"status":{"type":"string","enum":["PENDING","SCHEDULED","IN_PROGRESS","CLOSED","CANCELED"]},"stepModel":{"description":"How the onboarding holds its steps: ACTIONS (the onboarding steps and their plain tasks) or INTENTS (typed tasks under its ticket, run through the intent tools such as `executeEmployeeCreationIntent`). Null while it has neither a ticket nor a step, and for an onboarding run by the agent.","anyOf":[{"type":"string","enum":["ACTIONS","INTENTS"]},{"type":"null"}]},"stepProgress":{"description":"How many of its steps are through, out of how many: on ACTIONS its steps done, scheduled or skipped; otherwise the typed tasks of its ticket completed or cancelled. Null while it has no step.","anyOf":[{"type":"object","properties":{"done":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"total":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["done","total"],"additionalProperties":false},{"type":"null"}]},"source":{"type":"string","enum":["COCKPIT","MERGE","KOMBO","API"]},"suggestedEmail":{"anyOf":[{"type":"string"},{"type":"null"}]},"startDate":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"hrRecords":{"description":"HR records from the connected HRIS (Kombo) for this onboarding","type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"remoteId":{"anyOf":[{"type":"string"},{"type":"null"}]},"firstName":{"anyOf":[{"type":"string"},{"type":"null"}]},"lastName":{"anyOf":[{"type":"string"},{"type":"null"}]},"email":{"anyOf":[{"type":"string"},{"type":"null"}]},"personalEmail":{"anyOf":[{"type":"string"},{"type":"null"}]},"phone":{"anyOf":[{"type":"string"},{"type":"null"}]},"startDate":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"terminationDate":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]}},"required":["id"],"additionalProperties":false}},"hire":{"description":"The hire an admin added by hand in the cockpit short form, before they are an employee in Primo","anyOf":[{"type":"object","properties":{"firstName":{"type":"string"},"lastName":{"type":"string"},"personalEmail":{"description":"Where to reach the hire until their work mailbox exists","type":"string"},"rawText":{"description":"What the admin wrote about the hire, in their own words","anyOf":[{"type":"string"},{"type":"null"}]},"jobTitle":{"anyOf":[{"type":"string"},{"type":"null"}]},"teamId":{"description":"The Primo team the note names, when exactly one matches","anyOf":[{"type":"string"},{"type":"null"}]},"teamName":{"anyOf":[{"type":"string"},{"type":"null"}]},"managerId":{"description":"The Primo employee the note names as manager, when exactly one matches","anyOf":[{"type":"string"},{"type":"null"}]},"managerName":{"anyOf":[{"type":"string"},{"type":"null"}]},"workLocationId":{"description":"The Primo work location the note names, when exactly one matches","anyOf":[{"type":"string"},{"type":"null"}]},"workLocationName":{"anyOf":[{"type":"string"},{"type":"null"}]},"workMode":{"anyOf":[{"type":"string","enum":["REMOTE","ON_SITE","HYBRID"]},{"type":"null"}]},"city":{"anyOf":[{"type":"string"},{"type":"null"}]},"agentNotes":{"description":"What the note left ambiguous or could not file in a field, to ask or act on","type":"array","items":{"type":"string"}}},"required":["firstName","lastName","personalEmail","agentNotes"],"additionalProperties":false},{"type":"null"}]}},"required":["id","status","source","createdAt","hrRecords"],"additionalProperties":false},"order":{"description":"The order that was placed, or null when the step was executed without a purchase.","anyOf":[{"type":"object","properties":{"id":{"type":"string"},"reference":{"type":"string"},"status":{"type":"string"}},"required":["id","reference","status"],"additionalProperties":false},{"type":"null"}]}},"required":["onboarding"],"additionalProperties":false},"CreateEmailAccountIntentBody":{"type":"object","properties":{"groups":{"type":"array","items":{"type":"object","properties":{"id":{"description":"The entitlement id from `getSaasById` of the email provider","anyOf":[{"type":"string"},{"type":"null"}]},"name":{"type":"string","minLength":1}},"required":["id","name"]}},"roles":{"type":"array","items":{"type":"object","properties":{"id":{"description":"The entitlement id from `getSaasById` of the email provider","anyOf":[{"type":"string"},{"type":"null"}]},"name":{"type":"string","minLength":1}},"required":["id","name"]}},"licenses":{"type":"array","items":{"type":"object","properties":{"id":{"description":"The entitlement id from `getSaasById` of the email provider","anyOf":[{"type":"string"},{"type":"null"}]},"name":{"type":"string","minLength":1}},"required":["id","name"]}},"organizationUnits":{"type":"array","items":{"type":"object","properties":{"id":{"description":"The entitlement id from `getSaasById` of the email provider","anyOf":[{"type":"string"},{"type":"null"}]},"name":{"type":"string","minLength":1}},"required":["id","name"]}},"personalEmail":{"description":"The employee's personal address, saved on the employee on execute.","anyOf":[{"type":"string","format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},{"type":"null"}]},"employeeId":{"description":"The employee the mailbox is for (from `getEmployees`). Fixed once created.","type":"string","pattern":"^[a-f\\d]{24}$"},"credentialsRecipient":{"type":"object","properties":{"type":{"description":"Who receives the temporary password. EMPLOYEE sends it to `personalEmail`.","type":"string","enum":["ADMIN","EMPLOYEE","MANAGER","TASK_OWNER"]},"email":{"description":"The address the password is sent to","anyOf":[{"type":"string","format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},{"type":"string","const":""}]}},"required":["type","email"]},"parentTicketId":{"description":"The untyped ticket the work belongs to (an onboarding ticket). Omit it and Primo opens one.","anyOf":[{"type":"string","pattern":"^[a-f\\d]{24}$"},{"type":"null"}]},"scheduleDate":{"description":"Creates the task SCHEDULED until this date; the mailbox is created when it wakes up. Without it, the mailbox is created right away.","anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]}},"required":["employeeId","credentialsRecipient"]},"EmailAccountIntent_Output":{"type":"object","properties":{"id":{"type":"string","description":"Intent id — pass it to `updateEmailAccountIntent` and `executeEmailAccountIntent`"},"taskId":{"description":"The EMAIL_ACCOUNT task that tracks the mailbox","anyOf":[{"type":"string"},{"type":"null"}]},"ticketId":{"description":"The ticket holding that task: the parentTicketId sent, or the one Primo opened. Null if unreadable.","anyOf":[{"type":"string"},{"type":"null"}]},"employeeId":{"type":"string"},"companySaasApplicationId":{"type":"string","description":"The company's email provider"},"credentialsRecipient":{"type":"object","properties":{"type":{"description":"Who receives the temporary password. EMPLOYEE sends it to `personalEmail`.","type":"string","enum":["ADMIN","EMPLOYEE","MANAGER","TASK_OWNER"]},"email":{"description":"The address the password is sent to","anyOf":[{"type":"string","format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},{"type":"string","const":""}]}},"required":["type","email"],"additionalProperties":false},"personalEmail":{"anyOf":[{"type":"string"},{"type":"null"}]},"groups":{"type":"array","items":{"type":"object","properties":{"id":{"description":"The entitlement id from `getSaasById` of the email provider","anyOf":[{"type":"string"},{"type":"null"}]},"name":{"type":"string","minLength":1}},"required":["id","name"],"additionalProperties":false}},"roles":{"type":"array","items":{"type":"object","properties":{"id":{"description":"The entitlement id from `getSaasById` of the email provider","anyOf":[{"type":"string"},{"type":"null"}]},"name":{"type":"string","minLength":1}},"required":["id","name"],"additionalProperties":false}},"licenses":{"type":"array","items":{"type":"object","properties":{"id":{"description":"The entitlement id from `getSaasById` of the email provider","anyOf":[{"type":"string"},{"type":"null"}]},"name":{"type":"string","minLength":1}},"required":["id","name"],"additionalProperties":false}},"organizationUnits":{"type":"array","items":{"type":"object","properties":{"id":{"description":"The entitlement id from `getSaasById` of the email provider","anyOf":[{"type":"string"},{"type":"null"}]},"name":{"type":"string","minLength":1}},"required":["id","name"],"additionalProperties":false}},"createdEmail":{"description":"The address the provider created, null until executed","anyOf":[{"type":"string"},{"type":"null"}]},"executedAt":{"description":"When the mailbox was created; null while the intent can change","anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","taskId","ticketId","employeeId","companySaasApplicationId","credentialsRecipient","personalEmail","groups","roles","licenses","organizationUnits","createdEmail","executedAt","createdAt","updatedAt"],"additionalProperties":false},"UpdateEmailAccountIntentBody":{"type":"object","properties":{"groups":{"type":"array","items":{"type":"object","properties":{"id":{"description":"The entitlement id from `getSaasById` of the email provider","anyOf":[{"type":"string"},{"type":"null"}]},"name":{"type":"string","minLength":1}},"required":["id","name"]}},"roles":{"type":"array","items":{"type":"object","properties":{"id":{"description":"The entitlement id from `getSaasById` of the email provider","anyOf":[{"type":"string"},{"type":"null"}]},"name":{"type":"string","minLength":1}},"required":["id","name"]}},"licenses":{"type":"array","items":{"type":"object","properties":{"id":{"description":"The entitlement id from `getSaasById` of the email provider","anyOf":[{"type":"string"},{"type":"null"}]},"name":{"type":"string","minLength":1}},"required":["id","name"]}},"organizationUnits":{"type":"array","items":{"type":"object","properties":{"id":{"description":"The entitlement id from `getSaasById` of the email provider","anyOf":[{"type":"string"},{"type":"null"}]},"name":{"type":"string","minLength":1}},"required":["id","name"]}},"personalEmail":{"description":"The employee's personal address, saved on the employee on execute.","anyOf":[{"type":"string","format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},{"type":"null"}]},"credentialsRecipient":{"type":"object","properties":{"type":{"description":"Who receives the temporary password. EMPLOYEE sends it to `personalEmail`.","type":"string","enum":["ADMIN","EMPLOYEE","MANAGER","TASK_OWNER"]},"email":{"description":"The address the password is sent to","anyOf":[{"type":"string","format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},{"type":"string","const":""}]}},"required":["type","email"]}}},"ExecuteEmailAccountIntentResult_Output":{"type":"object","properties":{"outcome":{"type":"string","description":"ALREADY_EXECUTED: an earlier call or the wake-up created the mailbox — nothing was created again","enum":["EXECUTED","ALREADY_EXECUTED"]},"intent":{"type":"object","properties":{"id":{"description":"Intent id — pass it to `updateEmailAccountIntent` and `executeEmailAccountIntent`","type":"string"},"taskId":{"description":"The EMAIL_ACCOUNT task that tracks the mailbox","anyOf":[{"type":"string"},{"type":"null"}]},"ticketId":{"description":"The ticket holding that task: the parentTicketId sent, or the one Primo opened. Null if unreadable.","anyOf":[{"type":"string"},{"type":"null"}]},"employeeId":{"type":"string"},"companySaasApplicationId":{"description":"The company's email provider","type":"string"},"credentialsRecipient":{"type":"object","properties":{"type":{"description":"Who receives the temporary password. EMPLOYEE sends it to `personalEmail`.","type":"string","enum":["ADMIN","EMPLOYEE","MANAGER","TASK_OWNER"]},"email":{"description":"The address the password is sent to","anyOf":[{"type":"string","format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},{"type":"string","const":""}]}},"required":["type","email"],"additionalProperties":false},"personalEmail":{"anyOf":[{"type":"string"},{"type":"null"}]},"groups":{"type":"array","items":{"type":"object","properties":{"id":{"description":"The entitlement id from `getSaasById` of the email provider","anyOf":[{"type":"string"},{"type":"null"}]},"name":{"type":"string","minLength":1}},"required":["id","name"],"additionalProperties":false}},"roles":{"type":"array","items":{"type":"object","properties":{"id":{"description":"The entitlement id from `getSaasById` of the email provider","anyOf":[{"type":"string"},{"type":"null"}]},"name":{"type":"string","minLength":1}},"required":["id","name"],"additionalProperties":false}},"licenses":{"type":"array","items":{"type":"object","properties":{"id":{"description":"The entitlement id from `getSaasById` of the email provider","anyOf":[{"type":"string"},{"type":"null"}]},"name":{"type":"string","minLength":1}},"required":["id","name"],"additionalProperties":false}},"organizationUnits":{"type":"array","items":{"type":"object","properties":{"id":{"description":"The entitlement id from `getSaasById` of the email provider","anyOf":[{"type":"string"},{"type":"null"}]},"name":{"type":"string","minLength":1}},"required":["id","name"],"additionalProperties":false}},"createdEmail":{"description":"The address the provider created, null until executed","anyOf":[{"type":"string"},{"type":"null"}]},"executedAt":{"description":"When the mailbox was created; null while the intent can change","anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","taskId","ticketId","employeeId","companySaasApplicationId","credentialsRecipient","personalEmail","groups","roles","licenses","organizationUnits","createdEmail","executedAt","createdAt","updatedAt"],"additionalProperties":false}},"required":["outcome","intent"],"additionalProperties":false},"CreateEmployeeCreationIntentBody":{"type":"object","properties":{"firstName":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}]},"lastName":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}]},"email":{"description":"Work email address the employee is created with.","anyOf":[{"type":"string","format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},{"type":"null"}]},"personalEmail":{"anyOf":[{"type":"string","format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},{"type":"null"}]},"phone":{"anyOf":[{"type":"string"},{"type":"null"}]},"startDate":{"description":"First day of the employee (ISO 8601), past or future.","anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"employmentType":{"anyOf":[{"type":"string","enum":["INTERNAL","CONTRACTOR"]},{"type":"null"}]},"job":{"description":"Job title.","anyOf":[{"type":"object","properties":{"id":{"description":"Id of an existing record, when there is one. Omit it to create or match by name.","anyOf":[{"type":"string"},{"type":"null"}]},"name":{"type":"string","minLength":1}},"required":["name"]},{"type":"null"}]},"legalEntity":{"anyOf":[{"type":"object","properties":{"id":{"description":"Id of an existing record, when there is one. Omit it to create or match by name.","anyOf":[{"type":"string"},{"type":"null"}]},"name":{"type":"string","minLength":1}},"required":["name"]},{"type":"null"}]},"workLocation":{"description":"Office. Null for a remote employee.","anyOf":[{"type":"object","properties":{"id":{"description":"Id of an existing record, when there is one. Omit it to create or match by name.","anyOf":[{"type":"string"},{"type":"null"}]},"name":{"type":"string","minLength":1}},"required":["name"]},{"type":"null"}]},"teams":{"description":"Teams the employee joins, replaced whole.","type":"array","items":{"type":"object","properties":{"id":{"description":"Id of an existing record, when there is one. Omit it to create or match by name.","anyOf":[{"type":"string"},{"type":"null"}]},"name":{"type":"string","minLength":1}},"required":["name"]}},"managerId":{"description":"Primo employee id of the manager, from `getEmployees`.","anyOf":[{"type":"string","pattern":"^[a-f\\d]{24}$"},{"type":"null"}]},"address":{"description":"Personal (home) address of the employee.","anyOf":[{"type":"object","properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}]},"contactName":{"anyOf":[{"type":"string"},{"type":"null"}]},"phone":{"anyOf":[{"type":"string"},{"type":"null"}]},"street":{"type":"string","minLength":1},"complement":{"anyOf":[{"type":"string"},{"type":"null"}]},"postalCode":{"type":"string","minLength":1},"city":{"type":"string","minLength":1},"country":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}]},"countryCode":{"description":"ISO 3166-1 alpha-2 country code","anyOf":[{"type":"string"},{"type":"null"}]}},"required":["street","postalCode","city"]},{"type":"null"}]},"onboardingId":{"description":"The onboarding the employee is created for, from `getOnboardings`. Fixed once created.","type":"string","pattern":"^[a-f\\d]{24}$"},"parentTicketId":{"description":"The untyped ticket the task belongs to. Omit it and Primo opens a ticket to hold the task.","anyOf":[{"type":"string","pattern":"^[a-f\\d]{24}$"},{"type":"null"}]},"scheduleDate":{"description":"Creates the task SCHEDULED until this date: it cannot be executed before it wakes up as PENDING.","anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]}},"required":["onboardingId"]},"EmployeeCreationIntent_Output":{"type":"object","properties":{"id":{"type":"string","description":"Intent id — pass it to `updateEmployeeCreationIntent` and `executeEmployeeCreationIntent`"},"taskId":{"description":"The EMPLOYEE_CREATION task that tracks this employee creation","anyOf":[{"type":"string"},{"type":"null"}]},"ticketId":{"description":"The ticket holding that task: the parentTicketId sent, or the one Primo opened. Null if it could not be read back.","anyOf":[{"type":"string"},{"type":"null"}]},"onboardingId":{"type":"string"},"firstName":{"anyOf":[{"type":"string"},{"type":"null"}]},"lastName":{"anyOf":[{"type":"string"},{"type":"null"}]},"email":{"anyOf":[{"type":"string"},{"type":"null"}]},"personalEmail":{"anyOf":[{"type":"string"},{"type":"null"}]},"phone":{"anyOf":[{"type":"string"},{"type":"null"}]},"startDate":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"employmentType":{"anyOf":[{"type":"string","enum":["INTERNAL","CONTRACTOR"]},{"type":"null"}]},"job":{"anyOf":[{"type":"object","properties":{"id":{"anyOf":[{"type":"string"},{"type":"null"}]},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]},"legalEntity":{"anyOf":[{"type":"object","properties":{"id":{"anyOf":[{"type":"string"},{"type":"null"}]},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]},"workLocation":{"anyOf":[{"type":"object","properties":{"id":{"anyOf":[{"type":"string"},{"type":"null"}]},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]},"teams":{"type":"array","items":{"type":"object","properties":{"id":{"anyOf":[{"type":"string"},{"type":"null"}]},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false}},"managerId":{"anyOf":[{"type":"string"},{"type":"null"}]},"address":{"anyOf":[{"type":"object","properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}]},"contactName":{"anyOf":[{"type":"string"},{"type":"null"}]},"phone":{"anyOf":[{"type":"string"},{"type":"null"}]},"street":{"type":"string","minLength":1},"complement":{"anyOf":[{"type":"string"},{"type":"null"}]},"postalCode":{"type":"string","minLength":1},"city":{"type":"string","minLength":1},"country":{"anyOf":[{"type":"string"},{"type":"null"}]},"countryCode":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["name","contactName","phone","street","complement","postalCode","city","country","countryCode"],"additionalProperties":false},{"type":"null"}]},"employeeId":{"description":"The employee created on execute, null until then","anyOf":[{"type":"string"},{"type":"null"}]},"executedAt":{"description":"When the intent was executed; null while it can still change","anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","taskId","ticketId","onboardingId","firstName","lastName","email","personalEmail","phone","startDate","employmentType","job","legalEntity","workLocation","teams","managerId","address","employeeId","executedAt","createdAt","updatedAt"],"additionalProperties":false},"UpdateEmployeeCreationIntentBody":{"type":"object","properties":{"firstName":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}]},"lastName":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}]},"email":{"description":"Work email address the employee is created with.","anyOf":[{"type":"string","format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},{"type":"null"}]},"personalEmail":{"anyOf":[{"type":"string","format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},{"type":"null"}]},"phone":{"anyOf":[{"type":"string"},{"type":"null"}]},"startDate":{"description":"First day of the employee (ISO 8601), past or future.","anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"employmentType":{"anyOf":[{"type":"string","enum":["INTERNAL","CONTRACTOR"]},{"type":"null"}]},"job":{"description":"Job title.","anyOf":[{"type":"object","properties":{"id":{"description":"Id of an existing record, when there is one. Omit it to create or match by name.","anyOf":[{"type":"string"},{"type":"null"}]},"name":{"type":"string","minLength":1}},"required":["name"]},{"type":"null"}]},"legalEntity":{"anyOf":[{"type":"object","properties":{"id":{"description":"Id of an existing record, when there is one. Omit it to create or match by name.","anyOf":[{"type":"string"},{"type":"null"}]},"name":{"type":"string","minLength":1}},"required":["name"]},{"type":"null"}]},"workLocation":{"description":"Office. Null for a remote employee.","anyOf":[{"type":"object","properties":{"id":{"description":"Id of an existing record, when there is one. Omit it to create or match by name.","anyOf":[{"type":"string"},{"type":"null"}]},"name":{"type":"string","minLength":1}},"required":["name"]},{"type":"null"}]},"teams":{"description":"Teams the employee joins, replaced whole.","type":"array","items":{"type":"object","properties":{"id":{"description":"Id of an existing record, when there is one. Omit it to create or match by name.","anyOf":[{"type":"string"},{"type":"null"}]},"name":{"type":"string","minLength":1}},"required":["name"]}},"managerId":{"description":"Primo employee id of the manager, from `getEmployees`.","anyOf":[{"type":"string","pattern":"^[a-f\\d]{24}$"},{"type":"null"}]},"address":{"description":"Personal (home) address of the employee.","anyOf":[{"type":"object","properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}]},"contactName":{"anyOf":[{"type":"string"},{"type":"null"}]},"phone":{"anyOf":[{"type":"string"},{"type":"null"}]},"street":{"type":"string","minLength":1},"complement":{"anyOf":[{"type":"string"},{"type":"null"}]},"postalCode":{"type":"string","minLength":1},"city":{"type":"string","minLength":1},"country":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}]},"countryCode":{"description":"ISO 3166-1 alpha-2 country code","anyOf":[{"type":"string"},{"type":"null"}]}},"required":["street","postalCode","city"]},{"type":"null"}]}}},"ExecuteEmployeeCreationIntentResult_Output":{"type":"object","properties":{"outcome":{"type":"string","description":"ALREADY_EXECUTED: an earlier call did the work — nothing was created again","enum":["EXECUTED","ALREADY_EXECUTED"]},"intent":{"type":"object","properties":{"id":{"description":"Intent id — pass it to `updateEmployeeCreationIntent` and `executeEmployeeCreationIntent`","type":"string"},"taskId":{"description":"The EMPLOYEE_CREATION task that tracks this employee creation","anyOf":[{"type":"string"},{"type":"null"}]},"ticketId":{"description":"The ticket holding that task: the parentTicketId sent, or the one Primo opened. Null if it could not be read back.","anyOf":[{"type":"string"},{"type":"null"}]},"onboardingId":{"type":"string"},"firstName":{"anyOf":[{"type":"string"},{"type":"null"}]},"lastName":{"anyOf":[{"type":"string"},{"type":"null"}]},"email":{"anyOf":[{"type":"string"},{"type":"null"}]},"personalEmail":{"anyOf":[{"type":"string"},{"type":"null"}]},"phone":{"anyOf":[{"type":"string"},{"type":"null"}]},"startDate":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"employmentType":{"anyOf":[{"type":"string","enum":["INTERNAL","CONTRACTOR"]},{"type":"null"}]},"job":{"anyOf":[{"type":"object","properties":{"id":{"anyOf":[{"type":"string"},{"type":"null"}]},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]},"legalEntity":{"anyOf":[{"type":"object","properties":{"id":{"anyOf":[{"type":"string"},{"type":"null"}]},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]},"workLocation":{"anyOf":[{"type":"object","properties":{"id":{"anyOf":[{"type":"string"},{"type":"null"}]},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]},"teams":{"type":"array","items":{"type":"object","properties":{"id":{"anyOf":[{"type":"string"},{"type":"null"}]},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false}},"managerId":{"anyOf":[{"type":"string"},{"type":"null"}]},"address":{"anyOf":[{"type":"object","properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}]},"contactName":{"anyOf":[{"type":"string"},{"type":"null"}]},"phone":{"anyOf":[{"type":"string"},{"type":"null"}]},"street":{"type":"string","minLength":1},"complement":{"anyOf":[{"type":"string"},{"type":"null"}]},"postalCode":{"type":"string","minLength":1},"city":{"type":"string","minLength":1},"country":{"anyOf":[{"type":"string"},{"type":"null"}]},"countryCode":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["name","contactName","phone","street","complement","postalCode","city","country","countryCode"],"additionalProperties":false},{"type":"null"}]},"employeeId":{"description":"The employee created on execute, null until then","anyOf":[{"type":"string"},{"type":"null"}]},"executedAt":{"description":"When the intent was executed; null while it can still change","anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","taskId","ticketId","onboardingId","firstName","lastName","email","personalEmail","phone","startDate","employmentType","job","legalEntity","workLocation","teams","managerId","address","employeeId","executedAt","createdAt","updatedAt"],"additionalProperties":false}},"required":["outcome","intent"],"additionalProperties":false},"SaasSelectionIntent_Output":{"type":"object","properties":{"id":{"type":"string","description":"Intent id — pass it to `executeSaasSelectionIntent`"},"taskId":{"description":"The SAAS_SELECTION task (\"Configure SaaS provisioning\")","anyOf":[{"type":"string"},{"type":"null"}]},"ticketId":{"description":"The onboarding ticket holding that task. Null if unreadable.","anyOf":[{"type":"string"},{"type":"null"}]},"employeeId":{"type":"string"},"proposedApps":{"type":"array","description":"The applications proposed for the employee when the task opened, in the shape `apps` takes","items":{"type":"object","properties":{"saasId":{"description":"The SaaS application (`id` from `getSaas`)","type":"string"},"groups":{"type":"array","items":{"type":"object","properties":{"id":{"description":"The entitlement id from `getSaasById` of the application, or null for one only an admin knows by name","anyOf":[{"type":"string"},{"type":"null"}]},"name":{"type":"string","minLength":1}},"required":["id","name"],"additionalProperties":false}},"roles":{"type":"array","items":{"type":"object","properties":{"id":{"description":"The entitlement id from `getSaasById` of the application, or null for one only an admin knows by name","anyOf":[{"type":"string"},{"type":"null"}]},"name":{"type":"string","minLength":1}},"required":["id","name"],"additionalProperties":false}},"licenses":{"type":"array","items":{"type":"object","properties":{"id":{"description":"The entitlement id from `getSaasById` of the application, or null for one only an admin knows by name","anyOf":[{"type":"string"},{"type":"null"}]},"name":{"type":"string","minLength":1}},"required":["id","name"],"additionalProperties":false}},"organizationUnits":{"type":"array","items":{"type":"object","properties":{"id":{"description":"The entitlement id from `getSaasById` of the application, or null for one only an admin knows by name","anyOf":[{"type":"string"},{"type":"null"}]},"name":{"type":"string","minLength":1}},"required":["id","name"],"additionalProperties":false}},"credentialsRecipient":{"description":"Who receives the password of a new account; empty email for MANAGER or TASK_OWNER","anyOf":[{"type":"object","properties":{"type":{"description":"Who receives the temporary password of a new account. EMPLOYEE sends it to the personal email; MANAGER and TASK_OWNER are resolved when the account is created.","type":"string","enum":["ADMIN","EMPLOYEE","MANAGER","TASK_OWNER"]},"email":{"type":"string"}},"required":["type","email"],"additionalProperties":false},{"type":"null"}]}},"required":["saasId","groups","roles","licenses","organizationUnits","credentialsRecipient"],"additionalProperties":false}},"executedAt":{"description":"When the selection was validated; null while it is open","anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","taskId","ticketId","employeeId","proposedApps","executedAt","createdAt","updatedAt"],"additionalProperties":false},"ExecuteSaasSelectionIntentBody":{"type":"object","properties":{"apps":{"description":"The applications to open an account task for — start from `proposedApps` of `getSaasSelectionIntent`, then drop, add or adjust. An empty list opens none and completes the task.","type":"array","items":{"type":"object","properties":{"saasId":{"description":"The SaaS application (`id` from `getSaas`, or `saasId` of a proposed app)","type":"string","pattern":"^[a-f\\d]{24}$"},"groups":{"type":"array","items":{"type":"object","properties":{"id":{"description":"The entitlement id from `getSaasById` of the application, or null for one only an admin knows by name","anyOf":[{"type":"string"},{"type":"null"}]},"name":{"type":"string","minLength":1}},"required":["name"]}},"roles":{"type":"array","items":{"type":"object","properties":{"id":{"description":"The entitlement id from `getSaasById` of the application, or null for one only an admin knows by name","anyOf":[{"type":"string"},{"type":"null"}]},"name":{"type":"string","minLength":1}},"required":["name"]}},"licenses":{"type":"array","items":{"type":"object","properties":{"id":{"description":"The entitlement id from `getSaasById` of the application, or null for one only an admin knows by name","anyOf":[{"type":"string"},{"type":"null"}]},"name":{"type":"string","minLength":1}},"required":["name"]}},"organizationUnits":{"type":"array","items":{"type":"object","properties":{"id":{"description":"The entitlement id from `getSaasById` of the application, or null for one only an admin knows by name","anyOf":[{"type":"string"},{"type":"null"}]},"name":{"type":"string","minLength":1}},"required":["name"]}},"credentialsRecipient":{"anyOf":[{"type":"object","properties":{"type":{"description":"Who receives the temporary password of a new account. EMPLOYEE sends it to the personal email; MANAGER and TASK_OWNER are resolved when the account is created.","type":"string","enum":["ADMIN","EMPLOYEE","MANAGER","TASK_OWNER"]},"email":{"description":"The address the password is sent to; empty only for MANAGER or TASK_OWNER","anyOf":[{"type":"string","format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},{"type":"string","const":""}]}},"required":["type","email"]},{"type":"null"}]}},"required":["saasId"]}},"scheduleDate":{"description":"Creates each account task SCHEDULED until this date when it is in the future; without it they start now.","anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"personalEmail":{"description":"The employee's personal address, saved on the employee before the account tasks open.","anyOf":[{"type":"string","format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},{"type":"null"}]}},"required":["apps"]},"ExecuteSaasSelectionIntentResult_Output":{"type":"object","properties":{"outcome":{"type":"string","description":"ALREADY_EXECUTED: the selection was validated earlier — no account task was opened again","enum":["EXECUTED","ALREADY_EXECUTED"]},"intent":{"type":"object","properties":{"id":{"description":"Intent id — pass it to `executeSaasSelectionIntent`","type":"string"},"taskId":{"description":"The SAAS_SELECTION task (\"Configure SaaS provisioning\")","anyOf":[{"type":"string"},{"type":"null"}]},"ticketId":{"description":"The onboarding ticket holding that task. Null if unreadable.","anyOf":[{"type":"string"},{"type":"null"}]},"employeeId":{"type":"string"},"proposedApps":{"description":"The applications proposed for the employee when the task opened, in the shape `apps` takes","type":"array","items":{"type":"object","properties":{"saasId":{"description":"The SaaS application (`id` from `getSaas`)","type":"string"},"groups":{"type":"array","items":{"type":"object","properties":{"id":{"description":"The entitlement id from `getSaasById` of the application, or null for one only an admin knows by name","anyOf":[{"type":"string"},{"type":"null"}]},"name":{"type":"string","minLength":1}},"required":["id","name"],"additionalProperties":false}},"roles":{"type":"array","items":{"type":"object","properties":{"id":{"description":"The entitlement id from `getSaasById` of the application, or null for one only an admin knows by name","anyOf":[{"type":"string"},{"type":"null"}]},"name":{"type":"string","minLength":1}},"required":["id","name"],"additionalProperties":false}},"licenses":{"type":"array","items":{"type":"object","properties":{"id":{"description":"The entitlement id from `getSaasById` of the application, or null for one only an admin knows by name","anyOf":[{"type":"string"},{"type":"null"}]},"name":{"type":"string","minLength":1}},"required":["id","name"],"additionalProperties":false}},"organizationUnits":{"type":"array","items":{"type":"object","properties":{"id":{"description":"The entitlement id from `getSaasById` of the application, or null for one only an admin knows by name","anyOf":[{"type":"string"},{"type":"null"}]},"name":{"type":"string","minLength":1}},"required":["id","name"],"additionalProperties":false}},"credentialsRecipient":{"description":"Who receives the password of a new account; empty email for MANAGER or TASK_OWNER","anyOf":[{"type":"object","properties":{"type":{"description":"Who receives the temporary password of a new account. EMPLOYEE sends it to the personal email; MANAGER and TASK_OWNER are resolved when the account is created.","type":"string","enum":["ADMIN","EMPLOYEE","MANAGER","TASK_OWNER"]},"email":{"type":"string"}},"required":["type","email"],"additionalProperties":false},{"type":"null"}]}},"required":["saasId","groups","roles","licenses","organizationUnits","credentialsRecipient"],"additionalProperties":false}},"executedAt":{"description":"When the selection was validated; null while it is open","anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","taskId","ticketId","employeeId","proposedApps","executedAt","createdAt","updatedAt"],"additionalProperties":false}},"required":["outcome","intent"],"additionalProperties":false},"GetOffboardings_Output":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"employeeId":{"type":"string"},"ticketId":{"anyOf":[{"type":"string"},{"type":"null"}]},"status":{"type":"string","enum":["PENDING","SCHEDULED","IN_PROGRESS","CLOSED","CANCELED"]},"source":{"type":"string","enum":["COCKPIT","MERGE","KOMBO"]},"terminationDate":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","employeeId","status","source","terminationDate","createdAt"],"additionalProperties":false}},"pagination":{"type":"object","properties":{"totalElements":{"type":"integer","minimum":0,"maximum":9007199254740991},"totalPages":{"type":"integer","minimum":0,"maximum":9007199254740991},"page":{"type":"integer","minimum":1,"maximum":9007199254740991},"perPage":{"type":"integer","minimum":1,"maximum":100}},"required":["totalElements","totalPages","page","perPage"],"additionalProperties":false}},"required":["data","pagination"],"additionalProperties":false},"GetOffboarding_Output":{"type":"object","properties":{"id":{"type":"string"},"employeeId":{"type":"string"},"ticketId":{"anyOf":[{"type":"string"},{"type":"null"}]},"status":{"type":"string","enum":["PENDING","SCHEDULED","IN_PROGRESS","CLOSED","CANCELED"]},"source":{"type":"string","enum":["COCKPIT","MERGE","KOMBO"]},"terminationDate":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","employeeId","status","source","terminationDate","createdAt"],"additionalProperties":false}}},"security":[{"apikey":[]}]}