{"openapi":"3.1.0","info":{"title":"PreStartGo Console API","version":"1.0.0","description":"PreStartGo B2B compliance platform REST API","contact":{"name":"PreStartGo API Support","email":"support@prestartgo.com","url":"https://www2.prestartgo.com/developers"},"license":{"name":"Proprietary — PreStartGo Terms of Service","url":"https://www2.prestartgo.com/legal/terms"}},"servers":[{"url":"https://api.prestartgo.com","description":"production API"}],"tags":[{"name":"Equipment","description":"Manage equipment assets (owners, assignment, site deployment) and linked hardware (Interlocks — `deviceType: SIM` — and GoTags)."},{"name":"Tags","description":"GoTag (8-character serial; QR + NFC) lifecycle: provisioning, lookup, deactivation, and equipment linkage."},{"name":"Devices","description":"Interlock (`deviceType: SIM`) registration and status. Pair with a Tracker (`deviceType: TM`) to add cellular + GPS on top of the Interlock's BLE baseline."},{"name":"Checks","description":"Submit and review pre-start equipment inspections. Append-only audit pattern with mutable review/invalidation fields."},{"name":"Checklists","description":"Manage equipment checklist templates: questions, required scope, and version history."},{"name":"Defects","description":"Track equipment defects and state transitions through triage and resolution. Append-only history. Setting or lifting the out-of-service lockout is console-only (tagged `Defect Out-of-Service`, API keys rejected)."},{"name":"Observations","description":"Behavioural and environmental observations with workflow transitions, attached photos, and threaded comments."},{"name":"Sites","description":"Physical site locations — address, region, hierarchical groups. Parent for check-ins and site-scoped safety rules."},{"name":"Groups","description":"Hierarchical grouping of equipment for scoping of operations, licenses, and reporting."},{"name":"Zones","description":"Read zone geofences for telemetry boundary checks. Site-scoped zone CRUD and zone violation events are console-only (tagged `Site Zones` / `Zone Events`, API keys rejected)."},{"name":"Services","description":"Maintenance work orders: lifecycle, assignment, completion. Ties equipment to service scheduling."},{"name":"Alerts","description":"Platform-generated compliance and operational alerts (boundary breaches, defect thresholds, missed checks)."},{"name":"Documents","description":"Upload and retrieve equipment-associated documents (manuals, certificates, maintenance records)."},{"name":"Webhooks","description":"Subscribe to platform events over HTTPS. Signed deliveries, retry semantics, and replay of recent events."},{"name":"Telemetry","description":"Device telemetry and event streams from Trackers (`deviceType: TM`): position, status, boundary events. Cursor-paginated."},{"name":"Reports","description":"Request and retrieve asynchronous compliance and utilisation reports. Returns 201 + a report handle."},{"name":"Utilization","description":"Bucketed (hour / day / week) equipment-use data derived from interlock cycles."},{"name":"Compliance","description":"Three-layer compliance rollups: per-equipment, per-site, and per-organisation status and findings."}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"Firebase ID Token","description":"Firebase Authentication ID token from a signed-in console user."},"apiKeyAuth":{"type":"http","scheme":"bearer","bearerFormat":"PSG API Key","description":"PSG API key (psg_live_… or psg_test_…) issued from Settings → API Keys in the console. Scoped; obeys the same rate limits as the issuing organization."}},"parameters":{},"schemas":{}},"paths":{"/api/v1/equipment":{"get":{"operationId":"listEquipment","summary":"List equipment","description":"Returns a paginated list of equipment for the authenticated org. Supports filtering by site, group, status and search, and by the state a machine is in: `complianceState` (the state of its latest pre-start), `blockingDefect` (locked by a defect) and `serviceDue` (overdue for service). Each row carries its `complianceState`.","tags":["Equipment"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","maxLength":500},"required":false,"name":"after","in":"query"},{"schema":{"type":"string","format":"uuid"},"required":false,"name":"groupId","in":"query"},{"schema":{"type":"string","format":"uuid"},"required":false,"name":"siteId","in":"query"},{"schema":{"type":"string","enum":["ACTIVE","INACTIVE","MAINTENANCE","DECOMMISSIONED"]},"required":false,"name":"status","in":"query"},{"schema":{"type":"string","maxLength":100},"required":false,"name":"search","in":"query"},{"schema":{"type":"string","description":"Comma-separated pre-start compliance states to return: COMPLIANT (latest pre-start passed and is still valid), NON_COMPLIANT (latest pre-start failed, was incomplete, or was voided by a manager), EXPIRED (latest pre-start passed but its validity window has closed), NEVER_CHECKED (no submitted pre-start). Only ACTIVE (in service) machines are in these states, and each is in exactly one: a machine that is under maintenance, inactive or decommissioned has no pre-start obligation and matches none of them."},"required":false,"description":"Comma-separated pre-start compliance states to return: COMPLIANT (latest pre-start passed and is still valid), NON_COMPLIANT (latest pre-start failed, was incomplete, or was voided by a manager), EXPIRED (latest pre-start passed but its validity window has closed), NEVER_CHECKED (no submitted pre-start). Only ACTIVE (in service) machines are in these states, and each is in exactly one: a machine that is under maintenance, inactive or decommissioned has no pre-start obligation and matches none of them.","name":"complianceState","in":"query"},{"schema":{"type":"boolean","description":"true returns only machines locked by a defect: any non-deleted defect with blocksOperation set, so every pre-start on the machine fails until the lock is lifted. false returns only machines with no such defect. Resolved through the machine owner, so a borrowed machine counts."},"required":false,"description":"true returns only machines locked by a defect: any non-deleted defect with blocksOperation set, so every pre-start on the machine fails until the lock is lifted. false returns only machines with no such defect. Resolved through the machine owner, so a borrowed machine counts.","name":"blockingDefect","in":"query"},{"schema":{"type":"string","enum":["OVERDUE"],"description":"OVERDUE returns only ACTIVE machines whose next service date has passed or whose service-hours budget is spent."},"required":false,"description":"OVERDUE returns only ACTIVE machines whose next service date has passed or whose service-hours budget is spent.","name":"serviceDue","in":"query"}],"responses":{"200":{"description":"List of equipment","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"plantNumber":{"type":["string","null"]},"registrationNumber":{"type":["string","null"]},"make":{"type":["string","null"]},"model":{"type":["string","null"]},"photoUrl":{"type":["string","null"],"maxLength":2048,"format":"uri"},"status":{"type":"string","enum":["ACTIVE","INACTIVE","MAINTENANCE","DECOMMISSIONED"]},"currentHours":{"type":"integer"},"lastCheckAt":{"type":["string","null"],"format":"date-time"},"lastCheckResult":{"type":["string","null"],"enum":["PASS","PASS_WITH_DEFECTS","FAIL","INCOMPLETE","INVALIDATED",null],"description":"Result of the machine's most recent submitted pre-start check; null if it has never been checked. For an API-key caller, a pass whose validity window has closed reads INVALIDATED, as does a check a manager invalidated. A signed-in console user receives the recorded result and reads lastCheckValidUntil beside it."},"lastCheckValidUntil":{"type":["string","null"],"format":"date-time","description":"When the most recent check stops permitting operation: the end of its validity window. Null when the machine has never been checked, or for an older non-passing check recorded before every check carried a deadline. Always sent."},"groupId":{"type":["string","null"],"format":"uuid"},"groupName":{"type":"string"},"lockState":{"type":["string","null"],"enum":["UNREGISTERED","AWAITING_CONFIRM","LOCKED","UNLOCKED","OPERATOR_EXPIRED","SERVICE","BYPASS","ERROR",null]},"lockStateSource":{"type":["string","null"],"enum":["COMMAND","ADV",null],"description":"Where lockState came from: COMMAND = read over an authenticated Bluetooth connection; ADV = decoded from the Interlock's Bluetooth advertising, which is not authenticated; null = written by a server-side change, or no Interlock is fitted. Always sent."},"createdAt":{"type":"string","format":"date-time"},"defaultChecklistTemplateId":{"type":["string","null"],"format":"uuid"},"defaultServiceChecklistTemplateId":{"type":["string","null"],"format":"uuid","description":"This machine's own default SERVICE checklist (null when it inherits its group's, or has none). Always sent."},"activeAssignment":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid","description":"The equipment assignment id"},"agreementId":{"type":"string","format":"uuid","description":"The operating agreement the assignment sits under"},"operatingOrgId":{"type":"string","format":"uuid","description":"The org operating (borrowing) the machine"},"operatingOrgName":{"type":["string","null"],"description":"Name of the operating org"},"ownerOrgName":{"type":["string","null"],"description":"Name of the org that owns the machine"},"validFrom":{"type":"string","format":"date-time","description":"When the assignment started"},"validUntil":{"type":["string","null"],"format":"date-time","description":"When the assignment ends; null when it is open-ended"}},"required":["id","agreementId","operatingOrgId","operatingOrgName","ownerOrgName","validFrom","validUntil"],"description":"The machine's live operating assignment, when it is lent to another org (or borrowed from one). Null when the owner operates it, or when the caller is neither the owner nor the operating org. Always sent."},"tracker":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid","description":"The device id, as GET /devices/{id} takes it"},"serialNumber":{"type":"string","description":"The device's serial number, as /devices lists it"}},"required":["id","serialNumber"],"description":"The Tracker (`deviceType: TM`) fitted to this machine. Null when none is fitted, or its device row is gone. Always sent."},"lastKnownPosition":{"type":["object","null"],"properties":{"lat":{"type":"number","description":"Latitude, WGS 84"},"lng":{"type":"number","description":"Longitude, WGS 84"},"at":{"type":"string","format":"date-time","description":"When this position was recorded"},"source":{"type":"string","enum":["TRACKER","STAMP","CHECK"],"description":"Where the position came from: TRACKER = the fitted Tracker's latest GPS fix; STAMP = the machine's last-known position, written by each mobile-app action on it (pre-start, unlock, takeover, bypass) and by Tracker readings; CHECK = the location of its latest located pre-start, for machines last seen before the stamp existed."}},"required":["lat","lng","at","source"],"description":"The machine's last known position: the freshest of its Tracker fix and its last-known stamp, else its latest located pre-start by the caller's own org. Null when none is known, and for a caller that does not own the machine, except the operating org, which sees its own latest located pre-start taken since its assignment started, and an org whose site the machine is inducted at right now, which sees its own latest located pre-start taken since that induction started. Neither sees the Tracker or the stamp, whose times do not say when the fix was taken. Sent on the list and the detail; not on create or update responses."},"complianceState":{"type":"string","enum":["COMPLIANT","NON_COMPLIANT","EXPIRED","NEVER_CHECKED"],"description":"The machine's pre-start compliance state right now: COMPLIANT = its latest pre-start passed and is still valid; NON_COMPLIANT = its latest pre-start failed, was incomplete, or was voided by a manager; EXPIRED = its latest pre-start passed but the validity window has closed; NEVER_CHECKED = no submitted pre-start. Absent for a machine that is not in service (`status` other than ACTIVE): it has no pre-start obligation and is in none of the states. Filter the list with the `complianceState` query parameter. Sent on the list only; not on the detail, create or update responses."}},"required":["id","name","plantNumber","registrationNumber","make","model","photoUrl","status","currentHours","lastCheckAt","lastCheckResult","groupId","groupName","lockState","createdAt","defaultChecklistTemplateId"],"description":"Equipment list item response"}},"meta":{"type":"object","properties":{"limit":{"type":"number"},"hasMore":{"type":"boolean"},"nextCursor":{"type":["string","null"]},"server_time":{"type":"integer"}},"required":["limit","hasMore","nextCursor"]}},"required":["success","data","meta"],"description":"Cursor-paginated API success response"}}}}}},"post":{"operationId":"createEquipment","summary":"Create equipment","description":"Creates a new equipment item in the org. Requires EDITOR role or above.","tags":["Equipment"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"groupId":{"type":"string","format":"uuid"},"siteId":{"type":["string","null"],"format":"uuid"},"assignedGroupId":{"type":["string","null"],"format":"uuid"},"assignedFrom":{"type":["string","null"],"format":"date-time"},"assignedUntil":{"type":["string","null"],"format":"date-time"},"name":{"type":"string","minLength":1,"maxLength":255},"plantNumber":{"type":["string","null"],"maxLength":50},"registrationNumber":{"type":["string","null"],"maxLength":50},"serialNumber":{"type":["string","null"],"maxLength":100},"make":{"type":["string","null"],"maxLength":100},"model":{"type":["string","null"],"maxLength":100},"year":{"type":["integer","null"],"minimum":1900,"maximum":2100},"photoUrl":{"type":["string","null"],"maxLength":2048,"format":"uri"},"fuelType":{"type":["string","null"],"enum":["DIESEL","PETROL","LPG","ELECTRIC","HYBRID",null]},"fuelConsumptionPerHour":{"type":["number","null"],"exclusiveMinimum":0},"status":{"type":"string","enum":["ACTIVE","INACTIVE","MAINTENANCE","DECOMMISSIONED"],"default":"ACTIVE"},"currentHours":{"type":"integer","minimum":0,"default":0},"currentKilometers":{"type":"integer","minimum":0,"default":0},"checkValidityMinutes":{"type":["integer","null"],"minimum":1,"maximum":1440},"operatorTimeoutMinutes":{"type":["integer","null"],"minimum":1,"maximum":180},"spotterRequired":{"type":["boolean","null"]},"swmsRequired":{"type":"boolean","default":false},"serviceIntervalHours":{"type":["integer","null"],"minimum":1,"maximum":10000},"serviceIntervalDays":{"type":["integer","null"],"minimum":1,"maximum":3650},"lastServiceHours":{"type":["integer","null"],"minimum":0},"nextServiceHours":{"type":["integer","null"],"minimum":0},"nextServiceDate":{"type":["string","null"],"format":"date-time"},"serviceWarningHours":{"type":["integer","null"],"minimum":0,"maximum":1000},"serviceWarningDays":{"type":["integer","null"],"minimum":0,"maximum":365},"preventStartWhenOverdue":{"type":["boolean","null"]},"defaultChecklistTemplateId":{"type":["string","null"],"format":"uuid"},"defaultServiceChecklistTemplateId":{"type":["string","null"],"format":"uuid","description":"The SERVICE checklist a new service on this machine takes when none is chosen (an active SERVICE template of your organization). Overrides the group's default service checklist."},"checkValidityHours":{"type":["integer","null"],"minimum":1,"maximum":24,"description":"Deprecated: send checkValidityMinutes. Stored as hours × 60 when checkValidityMinutes is absent; removed in a future release."}},"required":["groupId","name"],"additionalProperties":false,"description":"Create a new equipment","example":{"groupId":"b1e2c3d4-0000-4000-8000-000000000001","name":"Cat 320 Excavator","plantNumber":"EX-042","make":"Caterpillar","model":"320","year":2022,"fuelType":"DIESEL","status":"ACTIVE","currentHours":1240,"currentKilometers":0,"serviceIntervalHours":250,"serviceWarningHours":25,"checkValidityMinutes":480}}}}},"responses":{"201":{"description":"Equipment created","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"plantNumber":{"type":["string","null"]},"registrationNumber":{"type":["string","null"]},"make":{"type":["string","null"]},"model":{"type":["string","null"]},"photoUrl":{"type":["string","null"],"maxLength":2048,"format":"uri"},"status":{"type":"string","enum":["ACTIVE","INACTIVE","MAINTENANCE","DECOMMISSIONED"]},"currentHours":{"type":"integer"},"lastCheckAt":{"type":["string","null"],"format":"date-time"},"lastCheckResult":{"type":["string","null"],"enum":["PASS","PASS_WITH_DEFECTS","FAIL","INCOMPLETE","INVALIDATED",null],"description":"Result of the machine's most recent submitted pre-start check; null if it has never been checked. For an API-key caller, a pass whose validity window has closed reads INVALIDATED, as does a check a manager invalidated. A signed-in console user receives the recorded result and reads lastCheckValidUntil beside it."},"lastCheckValidUntil":{"type":["string","null"],"format":"date-time","description":"When the most recent check stops permitting operation: the end of its validity window. Null when the machine has never been checked, or for an older non-passing check recorded before every check carried a deadline. Always sent."},"groupId":{"type":["string","null"],"format":"uuid"},"groupName":{"type":"string"},"lockState":{"type":["string","null"],"enum":["UNREGISTERED","AWAITING_CONFIRM","LOCKED","UNLOCKED","OPERATOR_EXPIRED","SERVICE","BYPASS","ERROR",null]},"lockStateSource":{"type":["string","null"],"enum":["COMMAND","ADV",null],"description":"Where lockState came from: COMMAND = read over an authenticated Bluetooth connection; ADV = decoded from the Interlock's Bluetooth advertising, which is not authenticated; null = written by a server-side change, or no Interlock is fitted. Always sent."},"createdAt":{"type":"string","format":"date-time"},"defaultChecklistTemplateId":{"type":["string","null"],"format":"uuid"},"defaultServiceChecklistTemplateId":{"type":["string","null"],"format":"uuid","description":"This machine's own default SERVICE checklist (null when it inherits its group's, or has none). Always sent."},"activeAssignment":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid","description":"The equipment assignment id"},"agreementId":{"type":"string","format":"uuid","description":"The operating agreement the assignment sits under"},"operatingOrgId":{"type":"string","format":"uuid","description":"The org operating (borrowing) the machine"},"operatingOrgName":{"type":["string","null"],"description":"Name of the operating org"},"ownerOrgName":{"type":["string","null"],"description":"Name of the org that owns the machine"},"validFrom":{"type":"string","format":"date-time","description":"When the assignment started"},"validUntil":{"type":["string","null"],"format":"date-time","description":"When the assignment ends; null when it is open-ended"}},"required":["id","agreementId","operatingOrgId","operatingOrgName","ownerOrgName","validFrom","validUntil"],"description":"The machine's live operating assignment, when it is lent to another org (or borrowed from one). Null when the owner operates it, or when the caller is neither the owner nor the operating org. Always sent."},"tracker":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid","description":"The device id, as GET /devices/{id} takes it"},"serialNumber":{"type":"string","description":"The device's serial number, as /devices lists it"}},"required":["id","serialNumber"],"description":"The Tracker (`deviceType: TM`) fitted to this machine. Null when none is fitted, or its device row is gone. Always sent."},"lastKnownPosition":{"type":["object","null"],"properties":{"lat":{"type":"number","description":"Latitude, WGS 84"},"lng":{"type":"number","description":"Longitude, WGS 84"},"at":{"type":"string","format":"date-time","description":"When this position was recorded"},"source":{"type":"string","enum":["TRACKER","STAMP","CHECK"],"description":"Where the position came from: TRACKER = the fitted Tracker's latest GPS fix; STAMP = the machine's last-known position, written by each mobile-app action on it (pre-start, unlock, takeover, bypass) and by Tracker readings; CHECK = the location of its latest located pre-start, for machines last seen before the stamp existed."}},"required":["lat","lng","at","source"],"description":"The machine's last known position: the freshest of its Tracker fix and its last-known stamp, else its latest located pre-start by the caller's own org. Null when none is known, and for a caller that does not own the machine, except the operating org, which sees its own latest located pre-start taken since its assignment started, and an org whose site the machine is inducted at right now, which sees its own latest located pre-start taken since that induction started. Neither sees the Tracker or the stamp, whose times do not say when the fix was taken. Sent on the list and the detail; not on create or update responses."},"complianceState":{"type":"string","enum":["COMPLIANT","NON_COMPLIANT","EXPIRED","NEVER_CHECKED"],"description":"The machine's pre-start compliance state right now: COMPLIANT = its latest pre-start passed and is still valid; NON_COMPLIANT = its latest pre-start failed, was incomplete, or was voided by a manager; EXPIRED = its latest pre-start passed but the validity window has closed; NEVER_CHECKED = no submitted pre-start. Absent for a machine that is not in service (`status` other than ACTIVE): it has no pre-start obligation and is in none of the states. Filter the list with the `complianceState` query parameter. Sent on the list only; not on the detail, create or update responses."}},"required":["id","name","plantNumber","registrationNumber","make","model","photoUrl","status","currentHours","lastCheckAt","lastCheckResult","groupId","groupName","lockState","createdAt","defaultChecklistTemplateId"],"description":"Equipment list item response"}},"required":["success","data"],"description":"Standard API success response"}}}}}}},"/api/v1/equipment/export":{"get":{"operationId":"exportEquipment","summary":"Export equipment","description":"Download equipment as CSV or XLSX file.","tags":["Equipment"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","enum":["csv","xlsx"],"default":"csv"},"required":false,"name":"format","in":"query"},{"schema":{"type":"string","maxLength":100},"required":false,"name":"search","in":"query"},{"schema":{"type":"string","format":"uuid"},"required":false,"name":"groupId","in":"query"},{"schema":{"type":"string","format":"uuid"},"required":false,"name":"siteId","in":"query"},{"schema":{"type":"string","enum":["ACTIVE","INACTIVE","MAINTENANCE","DECOMMISSIONED"]},"required":false,"name":"status","in":"query"},{"schema":{"type":"string","description":"Comma-separated pre-start compliance states to return: COMPLIANT (latest pre-start passed and is still valid), NON_COMPLIANT (latest pre-start failed, was incomplete, or was voided by a manager), EXPIRED (latest pre-start passed but its validity window has closed), NEVER_CHECKED (no submitted pre-start). Only ACTIVE (in service) machines are in these states, and each is in exactly one: a machine that is under maintenance, inactive or decommissioned has no pre-start obligation and matches none of them."},"required":false,"description":"Comma-separated pre-start compliance states to return: COMPLIANT (latest pre-start passed and is still valid), NON_COMPLIANT (latest pre-start failed, was incomplete, or was voided by a manager), EXPIRED (latest pre-start passed but its validity window has closed), NEVER_CHECKED (no submitted pre-start). Only ACTIVE (in service) machines are in these states, and each is in exactly one: a machine that is under maintenance, inactive or decommissioned has no pre-start obligation and matches none of them.","name":"complianceState","in":"query"},{"schema":{"type":"boolean","description":"true returns only machines locked by a defect: any non-deleted defect with blocksOperation set, so every pre-start on the machine fails until the lock is lifted. false returns only machines with no such defect. Resolved through the machine owner, so a borrowed machine counts."},"required":false,"description":"true returns only machines locked by a defect: any non-deleted defect with blocksOperation set, so every pre-start on the machine fails until the lock is lifted. false returns only machines with no such defect. Resolved through the machine owner, so a borrowed machine counts.","name":"blockingDefect","in":"query"},{"schema":{"type":"string","enum":["OVERDUE"],"description":"OVERDUE returns only ACTIVE machines whose next service date has passed or whose service-hours budget is spent."},"required":false,"description":"OVERDUE returns only ACTIVE machines whose next service date has passed or whose service-hours budget is spent.","name":"serviceDue","in":"query"}],"responses":{"200":{"description":"File download","content":{"application/octet-stream":{"schema":{"type":"string"}}}},"202":{"description":"Row count exceeds 10000 — generation queued as a background job. Retain `data.jobId` and poll `GET /api/v1/equipment/export/jobs/{jobId}` until `status` is `COMPLETED`, then download `fileUrl` (a short-lived signed URL, re-signed on each poll). Completion is not announced by any other channel.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"jobId":{"type":"string","format":"uuid"},"resource":{"type":"string"},"format":{"type":"string","enum":["csv","xlsx"]},"status":{"type":"string","enum":["PENDING","GENERATING","COMPLETED","FAILED"]},"rowCount":{"type":["integer","null"],"minimum":0},"fileUrl":{"type":["string","null"],"maxLength":2048,"format":"uri"},"fileSize":{"type":["integer","null"],"minimum":0},"errorMessage":{"type":["string","null"],"maxLength":2000},"createdAt":{"type":["string","null"],"format":"date-time"},"updatedAt":{"type":["string","null"],"format":"date-time"},"completedAt":{"type":["string","null"],"format":"date-time"}},"required":["jobId","resource","format","status","createdAt","updatedAt"],"description":"Async resource-export job status"}},"required":["success","data"],"description":"Standard API success response"}}}}}}},"/api/v1/equipment/export/jobs/{id}":{"get":{"operationId":"getEquipmentExportJob","summary":"Get equipment export job status","description":"Poll the status of a background export job (returned by GET /export when the row count exceeds 10000). Export files are kept for 30 days; a job past that window returns 404 whether or not the retention sweep has reached it yet.","tags":["Equipment"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Export job status","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"jobId":{"type":"string","format":"uuid"},"resource":{"type":"string"},"format":{"type":"string","enum":["csv","xlsx"]},"status":{"type":"string","enum":["PENDING","GENERATING","COMPLETED","FAILED"]},"rowCount":{"type":["integer","null"],"minimum":0},"fileUrl":{"type":["string","null"],"maxLength":2048,"format":"uri"},"fileSize":{"type":["integer","null"],"minimum":0},"errorMessage":{"type":["string","null"],"maxLength":2000},"createdAt":{"type":["string","null"],"format":"date-time"},"updatedAt":{"type":["string","null"],"format":"date-time"},"completedAt":{"type":["string","null"],"format":"date-time"}},"required":["jobId","resource","format","status","createdAt","updatedAt"],"description":"Async resource-export job status"}},"required":["success","data"],"description":"Standard API success response"}}}},"404":{"description":"Export job not found"}}}},"/api/v1/equipment/export/template":{"get":{"operationId":"exportEquipmentTemplate","summary":"Download equipment import template","description":"Download an XLSX template with headers, example row, and column descriptions for importing equipment.","tags":["Equipment"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"XLSX template file","content":{"application/octet-stream":{"schema":{"type":"string"}}}}}}},"/api/v1/equipment/import/preview":{"post":{"operationId":"previewEquipmentImport","summary":"Preview equipment import","description":"Parse and validate a CSV/XLSX file for importing equipment. Returns a preview with validation results.","tags":["Equipment"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"responses":{"200":{"description":"Import preview with validated rows","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"totalRows":{"type":"integer"},"validRows":{"type":"integer"},"errorRows":{"type":"integer"},"rows":{"type":"array","items":{"type":"object","properties":{"rowNumber":{"type":"integer"},"data":{"type":"object","additionalProperties":{}},"valid":{"type":"boolean"},"errors":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"message":{"type":"string"}},"required":["field","message"],"description":"Field-level import validation error"}}},"required":["rowNumber","data","valid","errors"],"description":"Preview row from parsed import file"}},"columns":{"type":"array","items":{"type":"string"}}},"required":["totalRows","validRows","errorRows","rows","columns"],"description":"Import preview with validated rows"}},"required":["success","data"],"description":"Standard API success response"}}}},"400":{"description":"Invalid file"}}}},"/api/v1/equipment/import/commit":{"post":{"operationId":"commitEquipmentImport","summary":"Commit equipment import","description":"Insert validated equipment rows in a single database transaction.","tags":["Equipment"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"rows":{"type":"array","items":{"type":"object","additionalProperties":{}},"minItems":1,"maxItems":10000}},"required":["rows"],"additionalProperties":false,"description":"Commit validated import rows"}}}},"responses":{"201":{"description":"Import commit result","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"imported":{"type":"integer"},"resource":{"type":"string"}},"required":["imported","resource"],"description":"Import commit result"}},"required":["success","data"],"description":"Standard API success response"}}}},"422":{"description":"One or more rows failed re-validation at commit time","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["IMPORT_VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":["string","null"]}},"required":["code","message","requestId"]}},"required":["success","error"]}}}}}}},"/api/v1/equipment/:id":{"get":{"operationId":"getEquipment","summary":"Get equipment","description":"Returns full details of a single asset by ID, including linked Interlock and tag information.","tags":["Equipment"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Equipment details","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"plantNumber":{"type":["string","null"]},"registrationNumber":{"type":["string","null"]},"make":{"type":["string","null"]},"model":{"type":["string","null"]},"photoUrl":{"type":["string","null"],"maxLength":2048,"format":"uri"},"status":{"type":"string","enum":["ACTIVE","INACTIVE","MAINTENANCE","DECOMMISSIONED"]},"currentHours":{"type":"integer"},"lastCheckAt":{"type":["string","null"],"format":"date-time"},"lastCheckResult":{"type":["string","null"],"enum":["PASS","PASS_WITH_DEFECTS","FAIL","INCOMPLETE","INVALIDATED",null],"description":"Result of the machine's most recent submitted pre-start check; null if it has never been checked. For an API-key caller, a pass whose validity window has closed reads INVALIDATED, as does a check a manager invalidated. A signed-in console user receives the recorded result and reads lastCheckValidUntil beside it."},"lastCheckValidUntil":{"type":["string","null"],"format":"date-time","description":"When the most recent check stops permitting operation: the end of its validity window. Null when the machine has never been checked, or for an older non-passing check recorded before every check carried a deadline. Always sent."},"groupId":{"type":["string","null"],"format":"uuid"},"groupName":{"type":"string"},"lockState":{"type":["string","null"],"enum":["UNREGISTERED","AWAITING_CONFIRM","LOCKED","UNLOCKED","OPERATOR_EXPIRED","SERVICE","BYPASS","ERROR",null]},"lockStateSource":{"type":["string","null"],"enum":["COMMAND","ADV",null],"description":"Where lockState came from: COMMAND = read over an authenticated Bluetooth connection; ADV = decoded from the Interlock's Bluetooth advertising, which is not authenticated; null = written by a server-side change, or no Interlock is fitted. Always sent."},"createdAt":{"type":"string","format":"date-time"},"defaultChecklistTemplateId":{"type":["string","null"],"format":"uuid"},"defaultServiceChecklistTemplateId":{"type":["string","null"],"format":"uuid","description":"This machine's own default SERVICE checklist (null when it inherits its group's, or has none). Always sent."},"activeAssignment":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid","description":"The equipment assignment id"},"agreementId":{"type":"string","format":"uuid","description":"The operating agreement the assignment sits under"},"operatingOrgId":{"type":"string","format":"uuid","description":"The org operating (borrowing) the machine"},"operatingOrgName":{"type":["string","null"],"description":"Name of the operating org"},"ownerOrgName":{"type":["string","null"],"description":"Name of the org that owns the machine"},"validFrom":{"type":"string","format":"date-time","description":"When the assignment started"},"validUntil":{"type":["string","null"],"format":"date-time","description":"When the assignment ends; null when it is open-ended"}},"required":["id","agreementId","operatingOrgId","operatingOrgName","ownerOrgName","validFrom","validUntil"],"description":"The machine's live operating assignment, when it is lent to another org (or borrowed from one). Null when the owner operates it, or when the caller is neither the owner nor the operating org. Always sent."},"tracker":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid","description":"The device id, as GET /devices/{id} takes it"},"serialNumber":{"type":"string","description":"The device's serial number, as /devices lists it"}},"required":["id","serialNumber"],"description":"The Tracker (`deviceType: TM`) fitted to this machine. Null when none is fitted, or its device row is gone. Always sent."},"lastKnownPosition":{"type":["object","null"],"properties":{"lat":{"type":"number","description":"Latitude, WGS 84"},"lng":{"type":"number","description":"Longitude, WGS 84"},"at":{"type":"string","format":"date-time","description":"When this position was recorded"},"source":{"type":"string","enum":["TRACKER","STAMP","CHECK"],"description":"Where the position came from: TRACKER = the fitted Tracker's latest GPS fix; STAMP = the machine's last-known position, written by each mobile-app action on it (pre-start, unlock, takeover, bypass) and by Tracker readings; CHECK = the location of its latest located pre-start, for machines last seen before the stamp existed."}},"required":["lat","lng","at","source"],"description":"The machine's last known position: the freshest of its Tracker fix and its last-known stamp, else its latest located pre-start. Null when none is known, and for a caller that does not own the machine, except the operating org, which sees its own latest located pre-start taken since its assignment started, and an org whose site the machine is inducted at right now, which sees its own latest located pre-start taken since that induction started. Neither sees the Tracker or the stamp, whose times do not say when the fix was taken. Always sent."},"complianceState":{"type":"string","enum":["COMPLIANT","NON_COMPLIANT","EXPIRED","NEVER_CHECKED"],"description":"The machine's pre-start compliance state right now: COMPLIANT = its latest pre-start passed and is still valid; NON_COMPLIANT = its latest pre-start failed, was incomplete, or was voided by a manager; EXPIRED = its latest pre-start passed but the validity window has closed; NEVER_CHECKED = no submitted pre-start. Absent for a machine that is not in service (`status` other than ACTIVE): it has no pre-start obligation and is in none of the states. Filter the list with the `complianceState` query parameter. Sent on the list only; not on the detail, create or update responses."},"serialNumber":{"type":["string","null"]},"year":{"type":["integer","null"]},"fuelType":{"type":["string","null"],"enum":["DIESEL","PETROL","LPG","ELECTRIC","HYBRID",null]},"fuelConsumptionPerHour":{"type":["number","null"]},"currentKilometers":{"type":"integer"},"currentFuelLevel":{"type":["integer","null"],"minimum":0,"maximum":8},"fuelRefillRequired":{"type":"boolean"},"outOfService":{"type":"boolean","description":"True when a non-deleted blocksOperation defect locks this equipment (WS-1)"},"checkValidityMinutes":{"type":"integer"},"operatorTimeoutMinutes":{"type":"integer"},"checkValidityHours":{"type":["integer","null"],"description":"Deprecated: use checkValidityMinutes. The pre-start timer rounded down to whole hours, never below 1; removed in a future release."},"spotterRequired":{"type":["boolean","null"]},"swmsRequired":{"type":"boolean"},"preventStartWhenOverdue":{"type":["boolean","null"]},"serviceIntervalHours":{"type":["integer","null"]},"serviceIntervalDays":{"type":["integer","null"]},"lastServiceHours":{"type":["integer","null"]},"serviceWarningHours":{"type":["integer","null"]},"serviceWarningDays":{"type":["integer","null"]},"nextServiceHours":{"type":["integer","null"]},"nextServiceDate":{"type":["string","null"],"format":"date-time"},"siteId":{"type":["string","null"],"format":"uuid"},"siteName":{"type":["string","null"]},"assignedOrgId":{"type":["string","null"],"format":"uuid"},"assignedGroupId":{"type":["string","null"],"format":"uuid"},"assignedFrom":{"type":["string","null"],"format":"date-time"},"assignedUntil":{"type":["string","null"],"format":"date-time"},"lock":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid"},"serialNumber":{"type":"string"},"state":{"type":"string","enum":["UNREGISTERED","AWAITING_CONFIRM","LOCKED","UNLOCKED","OPERATOR_EXPIRED","SERVICE","BYPASS","ERROR"]},"isOnline":{"type":"boolean"},"batteryLevel":{"type":["integer","null"]}},"required":["id","serialNumber","state","isOnline","batteryLevel"],"description":"Associated Interlock (`deviceType: SIM`)"},"tim":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid"},"serialNumber":{"type":"string"},"deviceType":{"type":"string","enum":["SIM","TM"]},"status":{"type":"string","enum":["ONLINE","OFFLINE","NEVER_CONNECTED"]},"lastSeenAt":{"type":["string","null"],"format":"date-time"},"device":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid","description":"The device id, as GET /devices/{id} takes it"},"serialNumber":{"type":"string","description":"The device's serial number, as /devices lists it"}},"required":["id","serialNumber"],"description":"The Tracker device behind this telemetry binding. Null when the device row is gone. Always sent."}},"required":["id","serialNumber","deviceType","status","lastSeenAt"],"description":"Associated telemetry device — a Tracker (`deviceType: TM`)"},"tags":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"code":{"type":"string"}},"required":["id","code"],"description":"Tag identifier"}},"configSources":{"type":"object","additionalProperties":{"type":"string","enum":["equipment","site","group","org","system"]}},"currentChecklistTemplateId":{"type":["string","null"],"format":"uuid"},"currentChecklistTemplateName":{"type":["string","null"]},"pendingAssignment":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid","description":"The equipment assignment id"},"agreementId":{"type":"string","format":"uuid","description":"The operating agreement the assignment sits under"},"operatingOrgId":{"type":"string","format":"uuid","description":"The org operating (borrowing) the machine"},"operatingOrgName":{"type":["string","null"],"description":"Name of the operating org"},"ownerOrgName":{"type":["string","null"],"description":"Name of the org that owns the machine"},"validFrom":{"type":"string","format":"date-time","description":"When the assignment started"},"validUntil":{"type":["string","null"],"format":"date-time","description":"When the assignment ends; null when it is open-ended"}},"required":["id","agreementId","operatingOrgId","operatingOrgName","ownerOrgName","validFrom","validUntil"],"description":"An assignment of this machine that has not ended but is not live: it starts later, or its end date has passed and it has not been closed yet. It lets nobody operate the machine, but no new assignment can be made until it is ended. Sent only to the machine's owner; null otherwise, and whenever activeAssignment is set. Always sent."}},"required":["id","name","plantNumber","registrationNumber","make","model","photoUrl","status","currentHours","lastCheckAt","lastCheckResult","groupId","groupName","lockState","createdAt","defaultChecklistTemplateId","serialNumber","year","fuelType","fuelConsumptionPerHour","currentKilometers","currentFuelLevel","fuelRefillRequired","outOfService","checkValidityMinutes","operatorTimeoutMinutes","checkValidityHours","spotterRequired","swmsRequired","preventStartWhenOverdue","serviceIntervalHours","serviceIntervalDays","lastServiceHours","serviceWarningHours","serviceWarningDays","nextServiceHours","nextServiceDate","siteId","siteName","assignedOrgId","assignedGroupId","assignedFrom","assignedUntil","lock","tim","tags","currentChecklistTemplateId","currentChecklistTemplateName"],"description":"Equipment detail response"}},"required":["success","data"],"description":"Standard API success response"}}}},"404":{"description":"Equipment not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}},"patch":{"operationId":"updateEquipment","summary":"Update equipment","description":"Updates an existing equipment item. Can also link or unlink an Interlock by setting deviceId.","tags":["Equipment"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"groupId":{"type":"string","format":"uuid"},"siteId":{"type":["string","null"],"format":"uuid"},"assignedGroupId":{"type":["string","null"],"format":"uuid"},"assignedFrom":{"type":["string","null"],"format":"date-time"},"assignedUntil":{"type":["string","null"],"format":"date-time"},"name":{"type":"string","minLength":1,"maxLength":255},"plantNumber":{"type":["string","null"],"maxLength":50},"registrationNumber":{"type":["string","null"],"maxLength":50},"serialNumber":{"type":["string","null"],"maxLength":100},"make":{"type":["string","null"],"maxLength":100},"model":{"type":["string","null"],"maxLength":100},"year":{"type":["integer","null"],"minimum":1900,"maximum":2100},"photoUrl":{"type":["string","null"],"maxLength":2048,"format":"uri"},"fuelType":{"type":["string","null"],"enum":["DIESEL","PETROL","LPG","ELECTRIC","HYBRID",null]},"fuelConsumptionPerHour":{"type":["number","null"],"exclusiveMinimum":0},"status":{"type":"string","enum":["ACTIVE","INACTIVE","MAINTENANCE","DECOMMISSIONED"]},"currentHours":{"type":"integer","minimum":0},"currentKilometers":{"type":"integer","minimum":0},"checkValidityMinutes":{"type":["integer","null"],"minimum":1,"maximum":1440},"operatorTimeoutMinutes":{"type":["integer","null"],"minimum":1,"maximum":180},"spotterRequired":{"type":["boolean","null"]},"swmsRequired":{"type":"boolean"},"serviceIntervalHours":{"type":["integer","null"],"minimum":1,"maximum":10000},"serviceIntervalDays":{"type":["integer","null"],"minimum":1,"maximum":3650},"lastServiceHours":{"type":["integer","null"],"minimum":0},"nextServiceHours":{"type":["integer","null"],"minimum":0},"nextServiceDate":{"type":["string","null"],"format":"date-time"},"serviceWarningHours":{"type":["integer","null"],"minimum":0,"maximum":1000},"serviceWarningDays":{"type":["integer","null"],"minimum":0,"maximum":365},"preventStartWhenOverdue":{"type":["boolean","null"]},"defaultChecklistTemplateId":{"type":["string","null"],"format":"uuid"},"defaultServiceChecklistTemplateId":{"type":["string","null"],"format":"uuid","description":"The SERVICE checklist a new service on this machine takes when none is chosen (an active SERVICE template of your organization). Overrides the group's default service checklist."},"checkValidityHours":{"type":["integer","null"],"minimum":1,"maximum":24,"description":"Deprecated: send checkValidityMinutes. Stored as hours × 60 when checkValidityMinutes is absent; removed in a future release."}},"additionalProperties":false,"description":"Update an existing equipment"}}}},"responses":{"200":{"description":"Equipment updated","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"plantNumber":{"type":["string","null"]},"registrationNumber":{"type":["string","null"]},"make":{"type":["string","null"]},"model":{"type":["string","null"]},"photoUrl":{"type":["string","null"],"maxLength":2048,"format":"uri"},"status":{"type":"string","enum":["ACTIVE","INACTIVE","MAINTENANCE","DECOMMISSIONED"]},"currentHours":{"type":"integer"},"lastCheckAt":{"type":["string","null"],"format":"date-time"},"lastCheckResult":{"type":["string","null"],"enum":["PASS","PASS_WITH_DEFECTS","FAIL","INCOMPLETE","INVALIDATED",null],"description":"Result of the machine's most recent submitted pre-start check; null if it has never been checked. For an API-key caller, a pass whose validity window has closed reads INVALIDATED, as does a check a manager invalidated. A signed-in console user receives the recorded result and reads lastCheckValidUntil beside it."},"lastCheckValidUntil":{"type":["string","null"],"format":"date-time","description":"When the most recent check stops permitting operation: the end of its validity window. Null when the machine has never been checked, or for an older non-passing check recorded before every check carried a deadline. Always sent."},"groupId":{"type":["string","null"],"format":"uuid"},"groupName":{"type":"string"},"lockState":{"type":["string","null"],"enum":["UNREGISTERED","AWAITING_CONFIRM","LOCKED","UNLOCKED","OPERATOR_EXPIRED","SERVICE","BYPASS","ERROR",null]},"lockStateSource":{"type":["string","null"],"enum":["COMMAND","ADV",null],"description":"Where lockState came from: COMMAND = read over an authenticated Bluetooth connection; ADV = decoded from the Interlock's Bluetooth advertising, which is not authenticated; null = written by a server-side change, or no Interlock is fitted. Always sent."},"createdAt":{"type":"string","format":"date-time"},"defaultChecklistTemplateId":{"type":["string","null"],"format":"uuid"},"defaultServiceChecklistTemplateId":{"type":["string","null"],"format":"uuid","description":"This machine's own default SERVICE checklist (null when it inherits its group's, or has none). Always sent."},"activeAssignment":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid","description":"The equipment assignment id"},"agreementId":{"type":"string","format":"uuid","description":"The operating agreement the assignment sits under"},"operatingOrgId":{"type":"string","format":"uuid","description":"The org operating (borrowing) the machine"},"operatingOrgName":{"type":["string","null"],"description":"Name of the operating org"},"ownerOrgName":{"type":["string","null"],"description":"Name of the org that owns the machine"},"validFrom":{"type":"string","format":"date-time","description":"When the assignment started"},"validUntil":{"type":["string","null"],"format":"date-time","description":"When the assignment ends; null when it is open-ended"}},"required":["id","agreementId","operatingOrgId","operatingOrgName","ownerOrgName","validFrom","validUntil"],"description":"The machine's live operating assignment, when it is lent to another org (or borrowed from one). Null when the owner operates it, or when the caller is neither the owner nor the operating org. Always sent."},"tracker":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid","description":"The device id, as GET /devices/{id} takes it"},"serialNumber":{"type":"string","description":"The device's serial number, as /devices lists it"}},"required":["id","serialNumber"],"description":"The Tracker (`deviceType: TM`) fitted to this machine. Null when none is fitted, or its device row is gone. Always sent."},"lastKnownPosition":{"type":["object","null"],"properties":{"lat":{"type":"number","description":"Latitude, WGS 84"},"lng":{"type":"number","description":"Longitude, WGS 84"},"at":{"type":"string","format":"date-time","description":"When this position was recorded"},"source":{"type":"string","enum":["TRACKER","STAMP","CHECK"],"description":"Where the position came from: TRACKER = the fitted Tracker's latest GPS fix; STAMP = the machine's last-known position, written by each mobile-app action on it (pre-start, unlock, takeover, bypass) and by Tracker readings; CHECK = the location of its latest located pre-start, for machines last seen before the stamp existed."}},"required":["lat","lng","at","source"],"description":"The machine's last known position: the freshest of its Tracker fix and its last-known stamp, else its latest located pre-start by the caller's own org. Null when none is known, and for a caller that does not own the machine, except the operating org, which sees its own latest located pre-start taken since its assignment started, and an org whose site the machine is inducted at right now, which sees its own latest located pre-start taken since that induction started. Neither sees the Tracker or the stamp, whose times do not say when the fix was taken. Sent on the list and the detail; not on create or update responses."},"complianceState":{"type":"string","enum":["COMPLIANT","NON_COMPLIANT","EXPIRED","NEVER_CHECKED"],"description":"The machine's pre-start compliance state right now: COMPLIANT = its latest pre-start passed and is still valid; NON_COMPLIANT = its latest pre-start failed, was incomplete, or was voided by a manager; EXPIRED = its latest pre-start passed but the validity window has closed; NEVER_CHECKED = no submitted pre-start. Absent for a machine that is not in service (`status` other than ACTIVE): it has no pre-start obligation and is in none of the states. Filter the list with the `complianceState` query parameter. Sent on the list only; not on the detail, create or update responses."}},"required":["id","name","plantNumber","registrationNumber","make","model","photoUrl","status","currentHours","lastCheckAt","lastCheckResult","groupId","groupName","lockState","createdAt","defaultChecklistTemplateId"],"description":"Equipment list item response"}},"required":["success","data"],"description":"Standard API success response"}}}}}},"delete":{"operationId":"deleteEquipment","summary":"Delete equipment","description":"Soft-deletes an asset. The asset is marked as deleted but retained for audit purposes.","tags":["Equipment"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"responses":{"204":{"description":"Equipment deleted"}}}},"/api/v1/equipment/:id/location/history":{"get":{"operationId":"getEquipmentLocationHistory","summary":"Get equipment location history","description":"Returns GPS location history from pre-start checks for an item fitted with an Interlock (`deviceType: SIM`).","tags":["Equipment"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","maxLength":500},"required":false,"name":"after","in":"query"},{"schema":{"type":["string","null"],"format":"date-time"},"required":false,"name":"from","in":"query"},{"schema":{"type":["string","null"],"format":"date-time"},"required":false,"name":"to","in":"query"}],"responses":{"200":{"description":"Location history","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"type":"object","properties":{"latitude":{"type":"number","minimum":-90,"maximum":90,"description":"WGS-84 latitude in decimal degrees (-90 to 90)"},"longitude":{"type":"number","minimum":-180,"maximum":180,"description":"WGS-84 longitude in decimal degrees (-180 to 180)"},"altitude":{"type":["number","null"],"minimum":-500,"maximum":10000},"speed":{"type":["number","null"],"minimum":0,"maximum":500},"heading":{"type":["number","null"],"minimum":0,"exclusiveMaximum":360},"accuracy":{"type":["number","null"],"minimum":0,"maximum":1000},"timestamp":{"type":["string","null"],"format":"date-time"}},"required":["latitude","longitude","timestamp"],"description":"Individual GPS location data point"}},"meta":{"type":"object","properties":{"limit":{"type":"number"},"hasMore":{"type":"boolean"},"nextCursor":{"type":["string","null"]},"server_time":{"type":"integer"}},"required":["limit","hasMore","nextCursor"]}},"required":["success","data","meta"],"description":"Cursor-paginated API success response"}}}}}}},"/api/v1/checks/export/jobs/{id}":{"get":{"operationId":"getChecksExportJob","summary":"Get checks export job status","description":"Poll the status of a background export job (returned by GET /export when the row count exceeds 10000). Export files are kept for 30 days; a job past that window returns 404 whether or not the retention sweep has reached it yet.","tags":["Checks"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Export job status","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"jobId":{"type":"string","format":"uuid"},"resource":{"type":"string"},"format":{"type":"string","enum":["csv","xlsx"]},"status":{"type":"string","enum":["PENDING","GENERATING","COMPLETED","FAILED"]},"rowCount":{"type":["integer","null"],"minimum":0},"fileUrl":{"type":["string","null"],"maxLength":2048,"format":"uri"},"fileSize":{"type":["integer","null"],"minimum":0},"errorMessage":{"type":["string","null"],"maxLength":2000},"createdAt":{"type":["string","null"],"format":"date-time"},"updatedAt":{"type":["string","null"],"format":"date-time"},"completedAt":{"type":["string","null"],"format":"date-time"}},"required":["jobId","resource","format","status","createdAt","updatedAt"],"description":"Async resource-export job status"}},"required":["success","data"],"description":"Standard API success response"}}}},"404":{"description":"Export job not found"}}}},"/api/v1/checks/export":{"post":{"operationId":"exportChecks","summary":"Export pre-start checks as CSV","description":"Exports selected pre-start checks as a CSV file. Provide an array of check IDs to export.","tags":["Checks"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"ids":{"type":"array","items":{"type":"string","format":"uuid"},"minItems":1,"maxItems":500}},"required":["ids"]}}}},"responses":{"200":{"description":"CSV export file","content":{"text/csv":{"schema":{"type":"string"}}}}}},"get":{"operationId":"exportChecksFiltered","summary":"Export pre-start checks by filter","description":"Downloads the checks matching the current list filters (equipment/site/operator/result/date-range) as a CSV or XLSX file — \"export\" means the filtered list, not the whole org. Distinct from POST /checks/export, which takes an explicit array of check IDs.","tags":["Checks"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","enum":["csv","xlsx"],"default":"csv"},"required":false,"name":"format","in":"query"},{"schema":{"type":"string","maxLength":100},"required":false,"name":"search","in":"query"},{"schema":{"type":"string","format":"uuid"},"required":false,"name":"equipmentId","in":"query"},{"schema":{"type":"string","format":"uuid"},"required":false,"name":"siteId","in":"query"},{"schema":{"type":"string","format":"uuid"},"required":false,"name":"userId","in":"query"},{"schema":{"type":"string","enum":["PASS","PASS_WITH_DEFECTS","FAIL","INCOMPLETE","INVALIDATED"],"description":"Export only checks with this outcome, as the caller reads it: for an API-key caller INVALIDATED also returns passes whose validity window has closed, and PASS or PASS_WITH_DEFECTS return only passes whose window is still open."},"required":false,"description":"Export only checks with this outcome, as the caller reads it: for an API-key caller INVALIDATED also returns passes whose validity window has closed, and PASS or PASS_WITH_DEFECTS return only passes whose window is still open.","name":"result","in":"query"},{"schema":{"type":["string","null"],"format":"date-time"},"required":false,"name":"from","in":"query"},{"schema":{"type":["string","null"],"format":"date-time"},"required":false,"name":"to","in":"query"},{"schema":{"type":"boolean","description":"true returns only checks flagged for supervisor review and not yet reviewed; false returns only checks that are not flagged."},"required":false,"description":"true returns only checks flagged for supervisor review and not yet reviewed; false returns only checks that are not flagged.","name":"needsReview","in":"query"},{"schema":{"type":"boolean","description":"true returns only checks on which another operator took over the machine (a hot seat); false returns only checks with no hot seat."},"required":false,"description":"true returns only checks on which another operator took over the machine (a hot seat); false returns only checks with no hot seat.","name":"hasHotSeat","in":"query"},{"schema":{"type":"string","enum":["own"],"description":"own returns only pre-starts performed by your own organization, leaving out a loan partner's pre-starts on lent or borrowed machines. An API-key caller already reads only its own organization's pre-starts, so for an API key this changes nothing. Omitted returns everything the caller may read."},"required":false,"description":"own returns only pre-starts performed by your own organization, leaving out a loan partner's pre-starts on lent or borrowed machines. An API-key caller already reads only its own organization's pre-starts, so for an API key this changes nothing. Omitted returns everything the caller may read.","name":"scope","in":"query"}],"responses":{"200":{"description":"File download","content":{"application/octet-stream":{"schema":{"type":"string"}}}},"202":{"description":"Row count exceeds the 10000-row inline limit — generation queued as a background job. Retain `data.jobId` and poll `GET /api/v1/checks/export/jobs/{jobId}` until `status` is `COMPLETED`, then download `fileUrl` (a short-lived signed URL, re-signed on each poll). Completion is not announced by any other channel.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"jobId":{"type":"string","format":"uuid"},"resource":{"type":"string"},"format":{"type":"string","enum":["csv","xlsx"]},"status":{"type":"string","enum":["PENDING","GENERATING","COMPLETED","FAILED"]},"rowCount":{"type":["integer","null"],"minimum":0},"fileUrl":{"type":["string","null"],"maxLength":2048,"format":"uri"},"fileSize":{"type":["integer","null"],"minimum":0},"errorMessage":{"type":["string","null"],"maxLength":2000},"createdAt":{"type":["string","null"],"format":"date-time"},"updatedAt":{"type":["string","null"],"format":"date-time"},"completedAt":{"type":["string","null"],"format":"date-time"}},"required":["jobId","resource","format","status","createdAt","updatedAt"],"description":"Async resource-export job status"}},"required":["success","data"],"description":"Standard API success response"}}}}}}},"/api/v1/checks/:id/document":{"get":{"operationId":"getCheckDocument","summary":"Download a check document PDF","description":"Renders a branded PDF of a single pre-start check — header details, the checklist structure (current template version, noted if it has since drifted from the version this check was submitted against), per-item responses with embedded photos/signatures, and the latest acknowledgment. A signed-in user also receives the PDF of a check another org performed on a machine the caller lent to it, masked: it names the performing org and leaves out that org's response values, notes, photos, signatures, review status and people's contacts, and any site that is not the caller's. A check performed by an org the caller borrows from is a 404 here, and an API key receives its own org's checks only.","tags":["Checks"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The check document PDF","content":{"application/pdf":{"schema":{"type":"string"}}}},"404":{"description":"Check not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}}},"/api/v1/checks/:id/document/email":{"post":{"operationId":"emailCheckDocument","summary":"Email a check document PDF","description":"Renders the check document PDF and emails it to the given recipients.","tags":["Checks"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"recipients":{"type":"array","items":{"type":"string"},"minItems":1,"maxItems":50}},"required":["recipients"],"additionalProperties":false,"description":"Email a check document PDF to recipients"}}}},"responses":{"200":{"description":"Document emailed","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"sent":{"type":"integer"}},"required":["sent"]}},"required":["success","data"],"description":"Standard API success response"}}}},"404":{"description":"Check not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}}},"/api/v1/checks":{"get":{"operationId":"listChecks","summary":"List all pre-start checks","description":"Returns a paginated list of pre-start checks for the authenticated org. Supports filtering by asset, site, status, and date range.","tags":["Checks"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","maxLength":500},"required":false,"name":"after","in":"query"},{"schema":{"type":"string","maxLength":100},"required":false,"name":"search","in":"query"},{"schema":{"type":"string","format":"uuid"},"required":false,"name":"equipmentId","in":"query"},{"schema":{"type":"string","format":"uuid"},"required":false,"name":"siteId","in":"query"},{"schema":{"type":"string","format":"uuid"},"required":false,"name":"userId","in":"query"},{"schema":{"type":"string","enum":["PASS","PASS_WITH_DEFECTS","FAIL","INCOMPLETE","INVALIDATED"],"description":"Return only checks with this outcome, as the caller reads it: for an API-key caller INVALIDATED also returns passes whose validity window has closed, and PASS or PASS_WITH_DEFECTS return only passes whose window is still open."},"required":false,"description":"Return only checks with this outcome, as the caller reads it: for an API-key caller INVALIDATED also returns passes whose validity window has closed, and PASS or PASS_WITH_DEFECTS return only passes whose window is still open.","name":"result","in":"query"},{"schema":{"type":["string","null"],"format":"date-time"},"required":false,"name":"from","in":"query"},{"schema":{"type":["string","null"],"format":"date-time"},"required":false,"name":"to","in":"query"},{"schema":{"type":"boolean","description":"true returns only checks flagged for supervisor review and not yet reviewed; false returns only checks that are not flagged."},"required":false,"description":"true returns only checks flagged for supervisor review and not yet reviewed; false returns only checks that are not flagged.","name":"needsReview","in":"query"},{"schema":{"type":"boolean","description":"true returns only checks on which another operator took over the machine (a hot seat); false returns only checks with no hot seat."},"required":false,"description":"true returns only checks on which another operator took over the machine (a hot seat); false returns only checks with no hot seat.","name":"hasHotSeat","in":"query"},{"schema":{"type":"string","enum":["own"],"description":"own returns only pre-starts performed by your own organization, leaving out a loan partner's pre-starts on lent or borrowed machines. An API-key caller already reads only its own organization's pre-starts, so for an API key this changes nothing. Omitted returns everything the caller may read."},"required":false,"description":"own returns only pre-starts performed by your own organization, leaving out a loan partner's pre-starts on lent or borrowed machines. An API-key caller already reads only its own organization's pre-starts, so for an API key this changes nothing. Omitted returns everything the caller may read.","name":"scope","in":"query"}],"responses":{"200":{"description":"The list of checks","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"result":{"type":"string","enum":["PASS","PASS_WITH_DEFECTS","FAIL","INCOMPLETE","INVALIDATED"],"description":"Outcome of the check. INVALIDATED marks a check a manager voided; for an API-key caller it also marks a pass whose validity window has closed. A signed-in console user receives the recorded outcome and compares validUntil itself."},"performedAt":{"type":"string","format":"date-time"},"validUntil":{"type":["string","null"],"format":"date-time"},"operatorValidUntil":{"type":["string","null"],"format":"date-time"},"hasDefects":{"type":"boolean"},"hasCriticalDefects":{"type":"boolean"},"equipment":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"}},"required":["id","name"],"description":"Inspected equipment (null for site-only checks)"},"site":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"}},"required":["id","name"],"description":"Site the check was recorded at. Null when the machine had no site, and on another org's check whose site is not one of the caller's own."},"hotSeatCount":{"type":"integer","minimum":0,"description":"Number of times the machine changed hands on this pre-start (a hot seat): another operator took over, or the original operator took it back. An operator confirming again after their own timeout is not counted."},"user":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"}},"required":["id","name"],"description":"Operator who performed the check"},"operator":{"type":["object","null"],"properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"Operator who performed the check, name-resolved for this org"},"performingOrg":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"}},"default":null,"required":["id","name"],"description":"Org that performed the check when it is not the caller's own: a loan partner's check on a shared machine, which only a signed-in console user receives. Null on the caller's own check, and always null for an API-key caller, which reads its own org's checks only. Always sent; an API that predates the field omitted it, which means the same as null."},"scanSource":{"type":["string","null"],"enum":["qr","nfc","serial",null],"description":"How the user reached the equipment-anchored action: QR scan, NFC tap, or manual serial entry."}},"required":["id","result","performedAt","validUntil","operatorValidUntil","hasDefects","hasCriticalDefects","equipment","user","operator"],"description":"Check list item response"}},"meta":{"type":"object","properties":{"limit":{"type":"number"},"hasMore":{"type":"boolean"},"nextCursor":{"type":["string","null"]},"server_time":{"type":"integer"}},"required":["limit","hasMore","nextCursor"]}},"required":["success","data","meta"],"description":"Cursor-paginated API success response","example":{"success":true,"data":[{"id":"f6a7b8c9-0000-4000-a000-000000000005","result":"PASS","performedAt":"2025-04-20T06:00:00.000Z","validUntil":"2025-04-20T14:00:00.000Z","operatorValidUntil":"2025-04-20T14:00:00.000Z","hasDefects":false,"hasCriticalDefects":false,"equipment":{"id":"a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11","name":"Cat 320 Excavator"},"site":{"id":"b1ffcd00-0000-4000-a000-000000000007","name":"Northern Depot"},"hotSeatCount":0,"user":{"id":"c2d3e4f5-0000-4000-a000-000000000002","name":"Jordan Referee"},"operator":{"userId":"c2d3e4f5-0000-4000-a000-000000000002","name":"Jordan Referee","nameSource":"PERSON","email":null,"phone":null},"performingOrg":null,"scanSource":"qr"}],"meta":{"limit":20,"hasMore":false,"nextCursor":null}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}}},"/api/v1/checks/review":{"get":{"operationId":"listChecksNeedingReview","summary":"List pre-start checks needing review","description":"Returns all pre-start checks that have been flagged and are awaiting manager review.","tags":["Checks"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","maxLength":500},"required":false,"name":"after","in":"query"}],"responses":{"200":{"description":"Checks needing review","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"result":{"type":"string","enum":["PASS","PASS_WITH_DEFECTS","FAIL","INCOMPLETE","INVALIDATED"],"description":"Outcome of the check. INVALIDATED marks a check a manager voided; for an API-key caller it also marks a pass whose validity window has closed. A signed-in console user receives the recorded outcome and compares validUntil itself."},"performedAt":{"type":"string","format":"date-time"},"validUntil":{"type":["string","null"],"format":"date-time"},"operatorValidUntil":{"type":["string","null"],"format":"date-time"},"hasDefects":{"type":"boolean"},"hasCriticalDefects":{"type":"boolean"},"equipment":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"}},"required":["id","name"],"description":"Inspected equipment (null for site-only checks)"},"site":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"}},"required":["id","name"],"description":"Site the check was recorded at. Null when the machine had no site, and on another org's check whose site is not one of the caller's own."},"hotSeatCount":{"type":"integer","minimum":0,"description":"Number of times the machine changed hands on this pre-start (a hot seat): another operator took over, or the original operator took it back. An operator confirming again after their own timeout is not counted."},"user":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"}},"required":["id","name"],"description":"Operator who performed the check"},"operator":{"type":["object","null"],"properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"Operator who performed the check, name-resolved for this org"},"performingOrg":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"}},"default":null,"required":["id","name"],"description":"Org that performed the check when it is not the caller's own: a loan partner's check on a shared machine, which only a signed-in console user receives. Null on the caller's own check, and always null for an API-key caller, which reads its own org's checks only. Always sent; an API that predates the field omitted it, which means the same as null."},"scanSource":{"type":["string","null"],"enum":["qr","nfc","serial",null],"description":"How the user reached the equipment-anchored action: QR scan, NFC tap, or manual serial entry."}},"required":["id","result","performedAt","validUntil","operatorValidUntil","hasDefects","hasCriticalDefects","equipment","user","operator"],"description":"Check list item response"}},"meta":{"type":"object","properties":{"limit":{"type":"number"},"hasMore":{"type":"boolean"},"nextCursor":{"type":["string","null"]},"server_time":{"type":"integer"}},"required":["limit","hasMore","nextCursor"]}},"required":["success","data","meta"],"description":"Cursor-paginated API success response"}}}}}}},"/api/v1/checks/:id/acknowledgments":{"get":{"operationId":"listCheckAcknowledgments","summary":"Get check acknowledgments","description":"Returns all operator acknowledgments for a pre-start check.","tags":["Checks"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Check acknowledgments","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"orgId":{"type":"string","format":"uuid"},"checkId":{"type":"string","format":"uuid"},"userId":{"type":"string","format":"uuid"},"acknowledgedAt":{"type":["string","null"],"format":"date-time"},"validUntil":{"type":["string","null"],"format":"date-time"},"latitude":{"type":["number","null"],"minimum":-90,"maximum":90,"description":"WGS-84 latitude in decimal degrees (-90 to 90)"},"longitude":{"type":["number","null"],"minimum":-180,"maximum":180,"description":"WGS-84 longitude in decimal degrees (-180 to 180)"},"createdAt":{"type":["string","null"],"format":"date-time"}},"required":["id","orgId","checkId","userId","acknowledgedAt","validUntil","createdAt"],"description":"Operator acknowledgment of a check"}}},"required":["success","data"],"description":"Standard API success response"}}}},"404":{"description":"Check not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}}},"/api/v1/checks/:id":{"get":{"operationId":"getCheck","summary":"Get a pre-start check by ID","description":"Returns full details of a pre-start check, including responses, acknowledgments, and associated defects.","tags":["Checks"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The check details","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"result":{"type":"string","enum":["PASS","PASS_WITH_DEFECTS","FAIL","INCOMPLETE","INVALIDATED"],"description":"Outcome of the check. INVALIDATED marks a check a manager voided; for an API-key caller it also marks a pass whose validity window has closed. A signed-in console user receives the recorded outcome and compares validUntil itself."},"performedAt":{"type":"string","format":"date-time"},"validUntil":{"type":["string","null"],"format":"date-time"},"operatorValidUntil":{"type":["string","null"],"format":"date-time"},"hasDefects":{"type":"boolean"},"hasCriticalDefects":{"type":"boolean"},"equipment":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"}},"required":["id","name"],"description":"Inspected equipment (null for site-only checks)"},"site":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"}},"required":["id","name"],"description":"Site the check was recorded at. Null when the machine had no site, and on another org's check whose site is not one of the caller's own."},"hotSeatCount":{"type":"integer","minimum":0,"description":"Number of times the machine changed hands on this pre-start (a hot seat): another operator took over, or the original operator took it back. An operator confirming again after their own timeout is not counted."},"user":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"}},"required":["id","name"],"description":"Operator who performed the check"},"operator":{"type":["object","null"],"properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"Operator who performed the check, name-resolved for this org"},"performingOrg":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"}},"default":null,"required":["id","name"],"description":"Org that performed the check when it is not the caller's own: a loan partner's check on a shared machine, which only a signed-in console user receives. Null on the caller's own check, and always null for an API-key caller, which reads its own org's checks only. Always sent; an API that predates the field omitted it, which means the same as null."},"scanSource":{"type":["string","null"],"enum":["qr","nfc","serial",null],"description":"How the user reached the equipment-anchored action: QR scan, NFC tap, or manual serial entry."},"loanDirection":{"type":["string","null"],"enum":["LENT","BORROWED",null],"description":"On a check another org performed (performingOrg set): LENT when the machine is the caller's and that org borrows it, BORROWED when the caller borrows it from that org. Null on the caller's own check, and always null for an API-key caller."},"defectsKeptByOwner":{"type":"boolean","description":"True on the caller's own check of a machine another org owns whose hire has ended: the defects its FAIL responses link to stay with the machine's owner and can no longer be opened by the caller."},"hoursAtCheck":{"type":["integer","null"],"minimum":0},"kmAtCheck":{"type":["integer","null"],"minimum":0},"fuelLevelAtCheck":{"type":["integer","null"],"minimum":0,"maximum":8},"latitude":{"type":["number","null"],"minimum":-90,"maximum":90,"description":"WGS-84 latitude in decimal degrees (-90 to 90)"},"longitude":{"type":["number","null"],"minimum":-180,"maximum":180,"description":"WGS-84 longitude in decimal degrees (-180 to 180)"},"proceedWithDefects":{"type":["boolean","null"]},"spotterRequired":{"type":"boolean"},"flagSpotterMissing":{"type":"boolean"},"flagOrphanedEquipment":{"type":"boolean"},"flagLicenseInvalid":{"type":"boolean"},"flagPossibleDuplicate":{"type":"boolean"},"flagSimMismatch":{"type":"boolean"},"flagOffline":{"type":"boolean"},"flagTimeSkew":{"type":"boolean"},"flagStaleCacheHours":{"type":["integer","null"]},"flagChecklistVersionMismatch":{"type":"boolean"},"flagCompanyReadOnly":{"type":"boolean","description":"True when the company's subscription was read-only as this check arrived. The check was still judged and recorded."},"needsReview":{"type":"boolean"},"reviewStatus":{"type":["string","null"],"enum":["PENDING","APPROVED","INVALIDATED",null]},"reviewedAt":{"type":["string","null"],"format":"date-time"},"reviewedByUserId":{"type":["string","null"],"format":"uuid"},"reviewNotes":{"type":["string","null"]},"spotterConfirmedAt":{"type":["string","null"],"format":"date-time"},"spotter":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"}},"required":["id","name"],"description":"Spotter who confirmed the check"},"confirmedBy":{"type":["object","null"],"properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"Spotter who confirmed the check, name-resolved for this org"},"template":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"version":{"type":"integer"},"isAvailable":{"type":"boolean","description":"True when the caller's org owns this template and it has not been deleted since, so it can be opened"}},"required":["id","name","version"],"description":"Checklist template used for this check"},"responses":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"itemId":{"type":"string","format":"uuid"},"itemName":{"type":"string","maxLength":255},"sectionName":{"type":"string","maxLength":255},"response":{"type":"string","enum":["PASS","FAIL","NA"]},"itemType":{"type":"string","enum":["PASS_FAIL","TEXT","NUMBER","SELECT","MULTI_SELECT","DATE","TIME","PHOTO","SIGNATURE","INSTRUCTION"]},"value":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Per-type captured answer; null for PASS_FAIL/INSTRUCTION items"},"notes":{"type":["string","null"]},"defectId":{"type":["string","null"],"format":"uuid"}},"required":["id","itemId","itemName","sectionName","response","notes","defectId"],"description":"Individual checklist item response"},"maxItems":500},"defects":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"title":{"type":["string","null"]},"severity":{"type":"string","enum":["LOW","MEDIUM","HIGH","CRITICAL"]},"status":{"type":"string","enum":["REPORTED","ACKNOWLEDGED","RESOLVED","CLOSED"]}},"required":["id","title","severity","status"],"description":"Defect raised during this check"},"maxItems":100},"warnings":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"zoneName":{"type":"string"},"message":{"type":"string"}},"required":["code","zoneName","message"],"description":"Non-terminal pre-start warning (e.g. hazard zone)"},"description":"Non-blocking zone warnings recorded with this check: hazard, exclusion, or no position at a site with zones. Empty when none applied, and on a check performed by another org."}},"required":["id","result","performedAt","validUntil","operatorValidUntil","hasDefects","hasCriticalDefects","equipment","user","operator","hoursAtCheck","kmAtCheck","fuelLevelAtCheck","latitude","longitude","proceedWithDefects","spotterRequired","flagSpotterMissing","flagOrphanedEquipment","flagLicenseInvalid","flagPossibleDuplicate","flagSimMismatch","flagOffline","flagTimeSkew","flagStaleCacheHours","flagChecklistVersionMismatch","flagCompanyReadOnly","needsReview","reviewStatus","reviewedAt","reviewedByUserId","reviewNotes","spotterConfirmedAt","spotter","confirmedBy","template","responses","defects"],"description":"Check detail response"}},"required":["success","data"],"description":"Standard API success response"}}}},"404":{"description":"Check not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}}},"/api/v1/checks/:id/invalidate":{"post":{"operationId":"invalidateCheck","summary":"Invalidate a pre-start check","description":"Marks a pre-start check as invalid with a reason. Used when a check was submitted in error or is no longer applicable. Fires the check.invalidated push, and records a signed LOCK command for the machine's Interlock unless the void leaves the machine covered: its most recent submitted check is a different check that is valid now and lasts at least as long as the voided one, meaning it has no validity window or its window ends at or after the voided check's. A voided check with no window is covered only by a check with none (D2, amended 2026-09-30). Nothing delivers a server-issued command to an Interlock yet, so voiding does not lock the machine today.","tags":["Checks"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"reason":{"type":"string","minLength":1,"maxLength":1000}},"required":["reason"],"additionalProperties":false,"description":"Invalidate a completed check"}}}},"responses":{"200":{"description":"Check invalidated","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"orgId":{"type":"string","format":"uuid"},"equipmentId":{"type":["string","null"],"format":"uuid"},"userId":{"type":"string","format":"uuid"},"siteId":{"type":["string","null"],"format":"uuid"},"checklistTemplateId":{"type":"string","format":"uuid"},"resolvedTemplateVersion":{"type":["integer","null"]},"authMethod":{"type":"string","enum":["STANDARD"],"default":"STANDARD"},"kioskSessionId":{"type":["string","null"],"format":"uuid"},"serviceId":{"type":["string","null"],"format":"uuid"},"status":{"type":"string","enum":["DRAFT","COMPLETED","INVALIDATED"]},"result":{"type":"string","enum":["PASS","PASS_WITH_DEFECTS","FAIL","INCOMPLETE","INVALIDATED"]},"hoursAtCheck":{"type":["integer","null"],"minimum":0},"kmAtCheck":{"type":["integer","null"],"minimum":0},"fuelLevelAtCheck":{"type":["integer","null"],"minimum":0,"maximum":8},"hasDefects":{"type":"boolean"},"hasCriticalDefects":{"type":"boolean"},"proceedWithDefects":{"type":["boolean","null"]},"validUntil":{"type":["string","null"],"format":"date-time"},"operatorValidUntil":{"type":["string","null"],"format":"date-time"},"localId":{"type":["string","null"],"maxLength":100},"spotterRequired":{"type":"boolean"},"spotterUserId":{"type":["string","null"],"format":"uuid"},"spotterConfirmedAt":{"type":["string","null"],"format":"date-time"},"spotterConfirmMethod":{"type":["string","null"],"enum":["QR_SCAN","BLE_PROXIMITY","MANUAL_CODE",null]},"spotterLatitude":{"type":["number","null"],"minimum":-90,"maximum":90,"description":"WGS-84 latitude in decimal degrees (-90 to 90)"},"spotterLongitude":{"type":["number","null"],"minimum":-180,"maximum":180,"description":"WGS-84 longitude in decimal degrees (-180 to 180)"},"latitude":{"type":["number","null"],"minimum":-90,"maximum":90,"description":"WGS-84 latitude in decimal degrees (-90 to 90)"},"longitude":{"type":["number","null"],"minimum":-180,"maximum":180,"description":"WGS-84 longitude in decimal degrees (-180 to 180)"},"performedAt":{"type":["string","null"],"format":"date-time"},"submittedAt":{"type":["string","null"],"format":"date-time"},"offlineCreatedAt":{"type":["string","null"],"format":"date-time"},"deviceId":{"type":["string","null"],"maxLength":100},"deviceClockOffsetMs":{"type":["integer","null"]},"timeTrustConfidence":{"type":["string","null"],"enum":["live","persisted","none",null],"description":"Mobile trusted-time confidence when stamping the check's performedAt."},"performedAtClaimed":{"type":["string","null"],"format":"date-time"},"flagOrphanedEquipment":{"type":"boolean"},"flagLicenseInvalid":{"type":"boolean"},"flagPossibleDuplicate":{"type":"boolean"},"flagSimMismatch":{"type":"boolean"},"flagOffline":{"type":"boolean"},"flagTimeSkew":{"type":"boolean"},"flagStaleCacheHours":{"type":["integer","null"],"minimum":0},"flagChecklistVersionMismatch":{"type":"boolean"},"flagSpotterMissing":{"type":"boolean"},"flagCompanyReadOnly":{"type":"boolean"},"needsReview":{"type":"boolean"},"reviewedAt":{"type":["string","null"],"format":"date-time"},"reviewedByUserId":{"type":["string","null"],"format":"uuid"},"reviewStatus":{"type":["string","null"],"enum":["PENDING","APPROVED","INVALIDATED",null]},"reviewNotes":{"type":["string","null"],"maxLength":2000},"scanSource":{"type":["string","null"],"enum":["qr","nfc","serial",null],"description":"How the user reached the equipment-anchored action: QR scan, NFC tap, or manual serial entry."},"createdAt":{"type":["string","null"],"format":"date-time"},"updatedAt":{"type":["string","null"],"format":"date-time"}},"required":["id","orgId","userId","checklistTemplateId","status","result","hasDefects","hasCriticalDefects","spotterRequired","performedAt","flagOrphanedEquipment","flagLicenseInvalid","flagPossibleDuplicate","flagSimMismatch","flagOffline","flagTimeSkew","flagChecklistVersionMismatch","flagSpotterMissing","flagCompanyReadOnly","needsReview","createdAt","updatedAt"]}},"required":["success","data"],"description":"Standard API success response"}}}},"400":{"description":"Check already invalidated","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}},"404":{"description":"Check not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}}},"/api/v1/checks/:id/review":{"post":{"operationId":"reviewCheck","summary":"Review a flagged pre-start check","description":"Approves or rejects a pre-start check that was flagged for manager review. Adds reviewer notes to the audit trail.","tags":["Checks"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["APPROVED","INVALIDATED"],"description":"The verdict: APPROVED keeps the result, INVALIDATED voids it (and can lock the machine)."},"notes":{"type":"string","maxLength":1000}},"required":["status"],"additionalProperties":false,"description":"Review a flagged check"}}}},"responses":{"200":{"description":"Check reviewed","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"orgId":{"type":"string","format":"uuid"},"equipmentId":{"type":["string","null"],"format":"uuid"},"userId":{"type":"string","format":"uuid"},"siteId":{"type":["string","null"],"format":"uuid"},"checklistTemplateId":{"type":"string","format":"uuid"},"resolvedTemplateVersion":{"type":["integer","null"]},"authMethod":{"type":"string","enum":["STANDARD"],"default":"STANDARD"},"kioskSessionId":{"type":["string","null"],"format":"uuid"},"serviceId":{"type":["string","null"],"format":"uuid"},"status":{"type":"string","enum":["DRAFT","COMPLETED","INVALIDATED"]},"result":{"type":"string","enum":["PASS","PASS_WITH_DEFECTS","FAIL","INCOMPLETE","INVALIDATED"]},"hoursAtCheck":{"type":["integer","null"],"minimum":0},"kmAtCheck":{"type":["integer","null"],"minimum":0},"fuelLevelAtCheck":{"type":["integer","null"],"minimum":0,"maximum":8},"hasDefects":{"type":"boolean"},"hasCriticalDefects":{"type":"boolean"},"proceedWithDefects":{"type":["boolean","null"]},"validUntil":{"type":["string","null"],"format":"date-time"},"operatorValidUntil":{"type":["string","null"],"format":"date-time"},"localId":{"type":["string","null"],"maxLength":100},"spotterRequired":{"type":"boolean"},"spotterUserId":{"type":["string","null"],"format":"uuid"},"spotterConfirmedAt":{"type":["string","null"],"format":"date-time"},"spotterConfirmMethod":{"type":["string","null"],"enum":["QR_SCAN","BLE_PROXIMITY","MANUAL_CODE",null]},"spotterLatitude":{"type":["number","null"],"minimum":-90,"maximum":90,"description":"WGS-84 latitude in decimal degrees (-90 to 90)"},"spotterLongitude":{"type":["number","null"],"minimum":-180,"maximum":180,"description":"WGS-84 longitude in decimal degrees (-180 to 180)"},"latitude":{"type":["number","null"],"minimum":-90,"maximum":90,"description":"WGS-84 latitude in decimal degrees (-90 to 90)"},"longitude":{"type":["number","null"],"minimum":-180,"maximum":180,"description":"WGS-84 longitude in decimal degrees (-180 to 180)"},"performedAt":{"type":["string","null"],"format":"date-time"},"submittedAt":{"type":["string","null"],"format":"date-time"},"offlineCreatedAt":{"type":["string","null"],"format":"date-time"},"deviceId":{"type":["string","null"],"maxLength":100},"deviceClockOffsetMs":{"type":["integer","null"]},"timeTrustConfidence":{"type":["string","null"],"enum":["live","persisted","none",null],"description":"Mobile trusted-time confidence when stamping the check's performedAt."},"performedAtClaimed":{"type":["string","null"],"format":"date-time"},"flagOrphanedEquipment":{"type":"boolean"},"flagLicenseInvalid":{"type":"boolean"},"flagPossibleDuplicate":{"type":"boolean"},"flagSimMismatch":{"type":"boolean"},"flagOffline":{"type":"boolean"},"flagTimeSkew":{"type":"boolean"},"flagStaleCacheHours":{"type":["integer","null"],"minimum":0},"flagChecklistVersionMismatch":{"type":"boolean"},"flagSpotterMissing":{"type":"boolean"},"flagCompanyReadOnly":{"type":"boolean"},"needsReview":{"type":"boolean"},"reviewedAt":{"type":["string","null"],"format":"date-time"},"reviewedByUserId":{"type":["string","null"],"format":"uuid"},"reviewStatus":{"type":["string","null"],"enum":["PENDING","APPROVED","INVALIDATED",null]},"reviewNotes":{"type":["string","null"],"maxLength":2000},"scanSource":{"type":["string","null"],"enum":["qr","nfc","serial",null],"description":"How the user reached the equipment-anchored action: QR scan, NFC tap, or manual serial entry."},"createdAt":{"type":["string","null"],"format":"date-time"},"updatedAt":{"type":["string","null"],"format":"date-time"}},"required":["id","orgId","userId","checklistTemplateId","status","result","hasDefects","hasCriticalDefects","spotterRequired","performedAt","flagOrphanedEquipment","flagLicenseInvalid","flagPossibleDuplicate","flagSimMismatch","flagOffline","flagTimeSkew","flagChecklistVersionMismatch","flagSpotterMissing","flagCompanyReadOnly","needsReview","createdAt","updatedAt"]}},"required":["success","data"],"description":"Standard API success response"}}}},"404":{"description":"Check not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}}},"/api/v1/checks/:id/confirm-spotter":{"post":{"operationId":"confirmCheckSpotter","summary":"Confirm spotter presence","description":"Records spotter confirmation on an existing check that requires a spotter. Validates that the spotter is a different user, and for MANUAL_CODE method, verifies the 6-digit code.","tags":["Checks"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"spotterUserId":{"type":"string","format":"uuid"},"spotterConfirmMethod":{"type":"string","enum":["QR_SCAN","BLE_PROXIMITY","MANUAL_CODE"]},"spotterLatitude":{"type":["number","null"],"minimum":-90,"maximum":90,"description":"WGS-84 latitude in decimal degrees (-90 to 90)"},"spotterLongitude":{"type":["number","null"],"minimum":-180,"maximum":180,"description":"WGS-84 longitude in decimal degrees (-180 to 180)"},"spotterCode":{"type":"string","minLength":6,"maxLength":6}},"required":["spotterUserId","spotterConfirmMethod"],"additionalProperties":false,"description":"Confirm spotter presence on an existing check"}}}},"responses":{"200":{"description":"Spotter confirmed","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"orgId":{"type":"string","format":"uuid"},"equipmentId":{"type":["string","null"],"format":"uuid"},"userId":{"type":"string","format":"uuid"},"siteId":{"type":["string","null"],"format":"uuid"},"checklistTemplateId":{"type":"string","format":"uuid"},"resolvedTemplateVersion":{"type":["integer","null"]},"authMethod":{"type":"string","enum":["STANDARD"],"default":"STANDARD"},"kioskSessionId":{"type":["string","null"],"format":"uuid"},"serviceId":{"type":["string","null"],"format":"uuid"},"status":{"type":"string","enum":["DRAFT","COMPLETED","INVALIDATED"]},"result":{"type":"string","enum":["PASS","PASS_WITH_DEFECTS","FAIL","INCOMPLETE","INVALIDATED"]},"hoursAtCheck":{"type":["integer","null"],"minimum":0},"kmAtCheck":{"type":["integer","null"],"minimum":0},"fuelLevelAtCheck":{"type":["integer","null"],"minimum":0,"maximum":8},"hasDefects":{"type":"boolean"},"hasCriticalDefects":{"type":"boolean"},"proceedWithDefects":{"type":["boolean","null"]},"validUntil":{"type":["string","null"],"format":"date-time"},"operatorValidUntil":{"type":["string","null"],"format":"date-time"},"localId":{"type":["string","null"],"maxLength":100},"spotterRequired":{"type":"boolean"},"spotterUserId":{"type":["string","null"],"format":"uuid"},"spotterConfirmedAt":{"type":["string","null"],"format":"date-time"},"spotterConfirmMethod":{"type":["string","null"],"enum":["QR_SCAN","BLE_PROXIMITY","MANUAL_CODE",null]},"spotterLatitude":{"type":["number","null"],"minimum":-90,"maximum":90,"description":"WGS-84 latitude in decimal degrees (-90 to 90)"},"spotterLongitude":{"type":["number","null"],"minimum":-180,"maximum":180,"description":"WGS-84 longitude in decimal degrees (-180 to 180)"},"latitude":{"type":["number","null"],"minimum":-90,"maximum":90,"description":"WGS-84 latitude in decimal degrees (-90 to 90)"},"longitude":{"type":["number","null"],"minimum":-180,"maximum":180,"description":"WGS-84 longitude in decimal degrees (-180 to 180)"},"performedAt":{"type":["string","null"],"format":"date-time"},"submittedAt":{"type":["string","null"],"format":"date-time"},"offlineCreatedAt":{"type":["string","null"],"format":"date-time"},"deviceId":{"type":["string","null"],"maxLength":100},"deviceClockOffsetMs":{"type":["integer","null"]},"timeTrustConfidence":{"type":["string","null"],"enum":["live","persisted","none",null],"description":"Mobile trusted-time confidence when stamping the check's performedAt."},"performedAtClaimed":{"type":["string","null"],"format":"date-time"},"flagOrphanedEquipment":{"type":"boolean"},"flagLicenseInvalid":{"type":"boolean"},"flagPossibleDuplicate":{"type":"boolean"},"flagSimMismatch":{"type":"boolean"},"flagOffline":{"type":"boolean"},"flagTimeSkew":{"type":"boolean"},"flagStaleCacheHours":{"type":["integer","null"],"minimum":0},"flagChecklistVersionMismatch":{"type":"boolean"},"flagSpotterMissing":{"type":"boolean"},"flagCompanyReadOnly":{"type":"boolean"},"needsReview":{"type":"boolean"},"reviewedAt":{"type":["string","null"],"format":"date-time"},"reviewedByUserId":{"type":["string","null"],"format":"uuid"},"reviewStatus":{"type":["string","null"],"enum":["PENDING","APPROVED","INVALIDATED",null]},"reviewNotes":{"type":["string","null"],"maxLength":2000},"scanSource":{"type":["string","null"],"enum":["qr","nfc","serial",null],"description":"How the user reached the equipment-anchored action: QR scan, NFC tap, or manual serial entry."},"createdAt":{"type":["string","null"],"format":"date-time"},"updatedAt":{"type":["string","null"],"format":"date-time"}},"required":["id","orgId","userId","checklistTemplateId","status","result","hasDefects","hasCriticalDefects","spotterRequired","performedAt","flagOrphanedEquipment","flagLicenseInvalid","flagPossibleDuplicate","flagSimMismatch","flagOffline","flagTimeSkew","flagChecklistVersionMismatch","flagSpotterMissing","flagCompanyReadOnly","needsReview","createdAt","updatedAt"]}},"required":["success","data"],"description":"Standard API success response"}}}},"404":{"description":"Check not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}},"409":{"description":"Spotter not required or already confirmed","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}},"422":{"description":"Validation failure (same user, invalid code, expired code)","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}}},"/api/v1/sites":{"get":{"operationId":"listSites","summary":"List sites","description":"Returns a paginated list of sites for the authenticated org. Sites represent physical locations where equipment operates.","tags":["Sites"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","maxLength":500},"required":false,"name":"after","in":"query"},{"schema":{"type":"string","maxLength":100},"required":false,"name":"search","in":"query"},{"schema":{"type":"boolean"},"required":false,"name":"isActive","in":"query"},{"schema":{"type":"string","description":"Comma-separated site ids to resolve (max 100)"},"required":false,"description":"Comma-separated site ids to resolve (max 100)","name":"ids","in":"query"}],"responses":{"200":{"description":"List of sites","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"code":{"type":["string","null"]},"city":{"type":["string","null"]},"state":{"type":["string","null"]},"latitude":{"type":["number","null"],"minimum":-90,"maximum":90,"description":"WGS-84 latitude in decimal degrees (-90 to 90)"},"longitude":{"type":["number","null"],"minimum":-180,"maximum":180,"description":"WGS-84 longitude in decimal degrees (-180 to 180)"},"radius":{"type":["integer","null"]},"boundaryType":{"type":"string","enum":["CIRCLE","POLYGON"]},"isActive":{"type":"boolean"},"activeDeployments":{"type":"integer"}},"required":["id","name","code","city","state","latitude","longitude","radius","boundaryType","isActive","activeDeployments"],"description":"Site list item response"}},"meta":{"type":"object","properties":{"limit":{"type":"number"},"hasMore":{"type":"boolean"},"nextCursor":{"type":["string","null"]},"server_time":{"type":"integer"}},"required":["limit","hasMore","nextCursor"]}},"required":["success","data","meta"],"description":"Cursor-paginated API success response"}}}}}},"post":{"operationId":"createSite","summary":"Create site","description":"Creates a new site in the org with location and compliance configuration.","tags":["Sites"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":255},"address":{"type":["string","null"],"maxLength":500},"city":{"type":["string","null"],"maxLength":100},"state":{"type":["string","null"],"maxLength":100},"postcode":{"type":["string","null"],"maxLength":20},"country":{"type":["string","null"],"maxLength":100},"latitude":{"type":["number","null"],"minimum":-90,"maximum":90,"description":"WGS-84 latitude in decimal degrees (-90 to 90)"},"longitude":{"type":["number","null"],"minimum":-180,"maximum":180,"description":"WGS-84 longitude in decimal degrees (-180 to 180)"},"timezone":{"type":"string","minLength":1,"maxLength":50,"default":"UTC"},"radiusMeters":{"type":"integer","minimum":0,"maximum":100000,"default":500},"boundaryType":{"type":"string","enum":["CIRCLE","POLYGON"],"default":"CIRCLE"},"polygon":{"type":["array","null"],"items":{"type":"object","properties":{"lat":{"type":"number","minimum":-90,"maximum":90,"description":"WGS-84 latitude in decimal degrees (-90 to 90)"},"lng":{"type":"number","minimum":-180,"maximum":180,"description":"WGS-84 longitude in decimal degrees (-180 to 180)"}},"required":["lat","lng"],"description":"A single WGS-84 polygon vertex (lat/lng in decimal degrees)"},"maxItems":1000},"alertOnEnter":{"type":"boolean","default":false},"alertOnExit":{"type":"boolean","default":false},"alertOnDwell":{"type":"boolean","default":false},"dwellTimeMinutes":{"type":["integer","null"],"minimum":1,"maximum":10080},"isActive":{"type":"boolean","default":true},"inductionRequired":{"type":["boolean","null"]},"inductionValidityDays":{"type":["integer","null"],"minimum":0,"maximum":3650,"description":"Deprecated: has no effect. A person's induction ends when their site roster grant's validUntil passes. Still accepted and returned; removed in a future release."},"equipmentInductionRequired":{"type":["boolean","null"]},"checkInRequired":{"type":["boolean","null"]},"autoCheckoutTime":{"type":["string","null"]},"allowWalkIn":{"type":"boolean","default":false},"toolboxRequired":{"type":["boolean","null"]},"toolboxGraceMinutes":{"type":["integer","null"],"minimum":1},"spotterRequired":{"type":["boolean","null"]},"requireDefectPhotos":{"type":["boolean","null"]},"checkValidityHours":{"type":["integer","null"],"minimum":1,"maximum":24,"description":"Deprecated: send checkValidityMinutes. Stored as hours × 60 when checkValidityMinutes is absent; removed in a future release."},"checkValidityMinutes":{"type":["integer","null"],"minimum":1,"maximum":1440},"operatorTimeoutMinutes":{"type":["integer","null"],"minimum":1,"maximum":180},"serviceIntervalHours":{"type":["integer","null"],"minimum":1,"maximum":10000},"serviceIntervalDays":{"type":["integer","null"],"minimum":1,"maximum":3650},"serviceWarningHours":{"type":["integer","null"],"minimum":0,"maximum":1000},"serviceWarningDays":{"type":["integer","null"],"minimum":0,"maximum":365},"preventStartWhenOverdue":{"type":["boolean","null"]},"requirePersonInduction":{"type":"boolean","default":false,"description":"Pre-start gate: the operator must hold a live grant on this site's roster (be inducted here). Needs the Site Check-In feature: without it the value is stored as false and nothing is enforced."},"requireToolboxAttendance":{"type":"boolean","default":false,"description":"Pre-start gate: the operator must have attended a toolbox talk at this site within toolboxRecencyHours. Needs the Site Check-In feature: without it the value is stored as false and nothing is enforced."},"toolboxRecencyHours":{"type":"integer","minimum":1,"default":24},"autoInductContractorEquipment":{"type":"boolean","default":false},"contactName":{"type":["string","null"],"minLength":1,"maxLength":255},"contactPhone":{"type":["string","null"],"minLength":1},"contactEmail":{"type":["string","null"]},"code":{"type":"string"}},"required":["name"],"additionalProperties":false,"description":"Create a new site"}}}},"responses":{"201":{"description":"Site created","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"code":{"type":["string","null"]},"city":{"type":["string","null"]},"state":{"type":["string","null"]},"latitude":{"type":["number","null"],"minimum":-90,"maximum":90,"description":"WGS-84 latitude in decimal degrees (-90 to 90)"},"longitude":{"type":["number","null"],"minimum":-180,"maximum":180,"description":"WGS-84 longitude in decimal degrees (-180 to 180)"},"radius":{"type":["integer","null"]},"boundaryType":{"type":"string","enum":["CIRCLE","POLYGON"]},"isActive":{"type":"boolean"},"activeDeployments":{"type":"integer"}},"required":["id","name","code","city","state","latitude","longitude","radius","boundaryType","isActive","activeDeployments"],"description":"Site list item response"}},"required":["success","data"],"description":"Standard API success response"}}}}}}},"/api/v1/sites/export":{"get":{"operationId":"exportSites","summary":"Export sites","description":"Download sites as CSV or XLSX file.","tags":["Sites"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","enum":["csv","xlsx"],"default":"csv"},"required":false,"name":"format","in":"query"},{"schema":{"type":"string","maxLength":100},"required":false,"name":"search","in":"query"}],"responses":{"200":{"description":"File download","content":{"application/octet-stream":{"schema":{"type":"string"}}}},"202":{"description":"Row count exceeds 10000 — generation queued as a background job. Retain `data.jobId` and poll `GET /api/v1/sites/export/jobs/{jobId}` until `status` is `COMPLETED`, then download `fileUrl` (a short-lived signed URL, re-signed on each poll). Completion is not announced by any other channel.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"jobId":{"type":"string","format":"uuid"},"resource":{"type":"string"},"format":{"type":"string","enum":["csv","xlsx"]},"status":{"type":"string","enum":["PENDING","GENERATING","COMPLETED","FAILED"]},"rowCount":{"type":["integer","null"],"minimum":0},"fileUrl":{"type":["string","null"],"maxLength":2048,"format":"uri"},"fileSize":{"type":["integer","null"],"minimum":0},"errorMessage":{"type":["string","null"],"maxLength":2000},"createdAt":{"type":["string","null"],"format":"date-time"},"updatedAt":{"type":["string","null"],"format":"date-time"},"completedAt":{"type":["string","null"],"format":"date-time"}},"required":["jobId","resource","format","status","createdAt","updatedAt"],"description":"Async resource-export job status"}},"required":["success","data"],"description":"Standard API success response"}}}}}}},"/api/v1/sites/export/jobs/{id}":{"get":{"operationId":"getSitesExportJob","summary":"Get sites export job status","description":"Poll the status of a background export job (returned by GET /export when the row count exceeds 10000). Export files are kept for 30 days; a job past that window returns 404 whether or not the retention sweep has reached it yet.","tags":["Sites"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Export job status","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"jobId":{"type":"string","format":"uuid"},"resource":{"type":"string"},"format":{"type":"string","enum":["csv","xlsx"]},"status":{"type":"string","enum":["PENDING","GENERATING","COMPLETED","FAILED"]},"rowCount":{"type":["integer","null"],"minimum":0},"fileUrl":{"type":["string","null"],"maxLength":2048,"format":"uri"},"fileSize":{"type":["integer","null"],"minimum":0},"errorMessage":{"type":["string","null"],"maxLength":2000},"createdAt":{"type":["string","null"],"format":"date-time"},"updatedAt":{"type":["string","null"],"format":"date-time"},"completedAt":{"type":["string","null"],"format":"date-time"}},"required":["jobId","resource","format","status","createdAt","updatedAt"],"description":"Async resource-export job status"}},"required":["success","data"],"description":"Standard API success response"}}}},"404":{"description":"Export job not found"}}}},"/api/v1/sites/export/template":{"get":{"operationId":"exportSitesTemplate","summary":"Download sites import template","description":"Download an XLSX template with headers, example row, and column descriptions for importing sites.","tags":["Sites"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"XLSX template file","content":{"application/octet-stream":{"schema":{"type":"string"}}}}}}},"/api/v1/sites/import/preview":{"post":{"operationId":"previewSitesImport","summary":"Preview sites import","description":"Parse and validate a CSV/XLSX file for importing sites. Returns a preview with validation results.","tags":["Sites"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"responses":{"200":{"description":"Import preview with validated rows","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"totalRows":{"type":"integer"},"validRows":{"type":"integer"},"errorRows":{"type":"integer"},"rows":{"type":"array","items":{"type":"object","properties":{"rowNumber":{"type":"integer"},"data":{"type":"object","additionalProperties":{}},"valid":{"type":"boolean"},"errors":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"message":{"type":"string"}},"required":["field","message"],"description":"Field-level import validation error"}}},"required":["rowNumber","data","valid","errors"],"description":"Preview row from parsed import file"}},"columns":{"type":"array","items":{"type":"string"}}},"required":["totalRows","validRows","errorRows","rows","columns"],"description":"Import preview with validated rows"}},"required":["success","data"],"description":"Standard API success response"}}}},"400":{"description":"Invalid file"}}}},"/api/v1/sites/import/commit":{"post":{"operationId":"commitSitesImport","summary":"Commit sites import","description":"Insert validated sites rows in a single database transaction.","tags":["Sites"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"rows":{"type":"array","items":{"type":"object","additionalProperties":{}},"minItems":1,"maxItems":10000}},"required":["rows"],"additionalProperties":false,"description":"Commit validated import rows"}}}},"responses":{"201":{"description":"Import commit result","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"imported":{"type":"integer"},"resource":{"type":"string"}},"required":["imported","resource"],"description":"Import commit result"}},"required":["success","data"],"description":"Standard API success response"}}}},"422":{"description":"One or more rows failed re-validation at commit time","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["IMPORT_VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":["string","null"]}},"required":["code","message","requestId"]}},"required":["success","error"]}}}}}}},"/api/v1/sites/:id":{"get":{"operationId":"getSite","summary":"Get site","description":"Returns full details of a single site by ID, including coordinates and compliance settings.","tags":["Sites"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Site details","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"code":{"type":["string","null"]},"city":{"type":["string","null"]},"state":{"type":["string","null"]},"latitude":{"type":["number","null"],"minimum":-90,"maximum":90,"description":"WGS-84 latitude in decimal degrees (-90 to 90)"},"longitude":{"type":["number","null"],"minimum":-180,"maximum":180,"description":"WGS-84 longitude in decimal degrees (-180 to 180)"},"radius":{"type":["integer","null"]},"boundaryType":{"type":"string","enum":["CIRCLE","POLYGON"]},"isActive":{"type":"boolean"},"activeDeployments":{"type":"integer"},"address":{"type":["string","null"]},"postcode":{"type":["string","null"]},"country":{"type":["string","null"]},"timezone":{"type":"string"},"polygon":{"type":["array","null"],"items":{"type":"object","properties":{"lat":{"type":"number","minimum":-90,"maximum":90,"description":"WGS-84 latitude in decimal degrees (-90 to 90)"},"lng":{"type":"number","minimum":-180,"maximum":180,"description":"WGS-84 longitude in decimal degrees (-180 to 180)"}},"required":["lat","lng"],"description":"A single WGS-84 polygon vertex (lat/lng in decimal degrees)"}},"alertOnEnter":{"type":"boolean"},"alertOnExit":{"type":"boolean"},"alertOnDwell":{"type":"boolean"},"dwellTimeMinutes":{"type":["integer","null"]},"autoDisable":{"type":"boolean"},"inductionRequired":{"type":["boolean","null"]},"inductionValidityDays":{"type":["integer","null"],"description":"Deprecated: has no effect. A person's induction ends when their site roster grant's validUntil passes. Removed in a future release."},"equipmentInductionRequired":{"type":["boolean","null"]},"checkInRequired":{"type":["boolean","null"]},"autoCheckoutTime":{"type":["string","null"]},"allowWalkIn":{"type":"boolean"},"toolboxRequired":{"type":["boolean","null"]},"toolboxGraceMinutes":{"type":["integer","null"]},"spotterRequired":{"type":["boolean","null"]},"requireDefectPhotos":{"type":["boolean","null"]},"checkValidityMinutes":{"type":["integer","null"]},"checkValidityHours":{"type":["integer","null"],"description":"Deprecated: use checkValidityMinutes. The pre-start timer rounded down to whole hours, never below 1; removed in a future release."},"operatorTimeoutMinutes":{"type":["integer","null"]},"serviceIntervalHours":{"type":["integer","null"]},"serviceIntervalDays":{"type":["integer","null"]},"serviceWarningHours":{"type":["integer","null"]},"serviceWarningDays":{"type":["integer","null"]},"preventStartWhenOverdue":{"type":["boolean","null"]},"unlockDurationSeconds":{"type":["integer","null"]},"alertOnIgnition":{"type":["boolean","null"]},"deviceCheckValidityMinutes":{"type":["integer","null"]},"deviceOperatorTimeoutMinutes":{"type":["integer","null"]},"bypassButtonEnabled":{"type":["boolean","null"]},"requirePersonInduction":{"type":"boolean","description":"Pre-start gate: the operator must hold a live grant on this site's roster (be inducted here). Enforced only while the org has the Site Check-In feature"},"requireToolboxAttendance":{"type":"boolean","description":"Pre-start gate: the operator must have attended a toolbox talk at this site within toolboxRecencyHours. Enforced only while the org has the Site Check-In feature"},"toolboxRecencyHours":{"type":"integer","minimum":1,"description":"How recent, in hours, a toolbox attendance must be to satisfy requireToolboxAttendance"},"autoInductContractorEquipment":{"type":"boolean"},"contactName":{"type":["string","null"]},"contactPhone":{"type":["string","null"]},"contactEmail":{"type":["string","null"]},"equipment":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"status":{"type":"string","enum":["ACTIVE","INACTIVE","MAINTENANCE","DECOMMISSIONED"]}},"required":["id","name","status"],"description":"Deployed equipment"}},"zones":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"type":{"type":"string","enum":["CIRCLE","POLYGON"]},"isActive":{"type":"boolean"}},"required":["id","name","type","isActive"],"description":"Site zone"}},"kiosks":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"deviceName":{"type":"string"},"status":{"type":"string","enum":["ACTIVE","SUSPENDED","ENDED","REVOKED"]}},"required":["id","deviceName","status"],"description":"Site kiosk"}},"recentSpotChecks":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"outcome":{"type":"string","enum":["COMPLIANT","OBSERVATION","WARNING","NON_COMPLIANT"]},"performedAt":{"type":"string","format":"date-time"}},"required":["id","outcome","performedAt"],"description":"Recent spot check"}}},"required":["id","name","code","city","state","latitude","longitude","radius","boundaryType","isActive","activeDeployments","address","postcode","country","timezone","polygon","alertOnEnter","alertOnExit","alertOnDwell","dwellTimeMinutes","autoDisable","inductionRequired","inductionValidityDays","equipmentInductionRequired","checkInRequired","autoCheckoutTime","allowWalkIn","toolboxRequired","toolboxGraceMinutes","spotterRequired","requireDefectPhotos","checkValidityMinutes","checkValidityHours","operatorTimeoutMinutes","serviceIntervalHours","serviceIntervalDays","serviceWarningHours","serviceWarningDays","preventStartWhenOverdue","unlockDurationSeconds","alertOnIgnition","deviceCheckValidityMinutes","deviceOperatorTimeoutMinutes","bypassButtonEnabled","autoInductContractorEquipment","contactName","contactPhone","contactEmail","equipment","zones","kiosks","recentSpotChecks"],"description":"Site detail response"}},"required":["success","data"],"description":"Standard API success response"}}}},"404":{"description":"Site not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}},"patch":{"operationId":"updateSite","summary":"Update site","description":"Updates an existing site's details, location, or compliance settings.","tags":["Sites"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":255},"address":{"type":["string","null"],"maxLength":500},"city":{"type":["string","null"],"maxLength":100},"state":{"type":["string","null"],"maxLength":100},"postcode":{"type":["string","null"],"maxLength":20},"country":{"type":["string","null"],"maxLength":100},"latitude":{"type":["number","null"],"minimum":-90,"maximum":90,"description":"WGS-84 latitude in decimal degrees (-90 to 90)"},"longitude":{"type":["number","null"],"minimum":-180,"maximum":180,"description":"WGS-84 longitude in decimal degrees (-180 to 180)"},"timezone":{"type":"string","minLength":1,"maxLength":50},"radiusMeters":{"type":"integer","minimum":0,"maximum":100000},"boundaryType":{"type":"string","enum":["CIRCLE","POLYGON"]},"polygon":{"type":["array","null"],"items":{"type":"object","properties":{"lat":{"type":"number","minimum":-90,"maximum":90,"description":"WGS-84 latitude in decimal degrees (-90 to 90)"},"lng":{"type":"number","minimum":-180,"maximum":180,"description":"WGS-84 longitude in decimal degrees (-180 to 180)"}},"required":["lat","lng"],"description":"A single WGS-84 polygon vertex (lat/lng in decimal degrees)"},"maxItems":1000},"alertOnEnter":{"type":"boolean"},"alertOnExit":{"type":"boolean"},"alertOnDwell":{"type":"boolean"},"dwellTimeMinutes":{"type":["integer","null"],"minimum":1,"maximum":10080},"isActive":{"type":"boolean"},"inductionRequired":{"type":["boolean","null"]},"inductionValidityDays":{"type":["integer","null"],"minimum":0,"maximum":3650,"description":"Deprecated: has no effect. A person's induction ends when their site roster grant's validUntil passes. Still accepted and returned; removed in a future release."},"equipmentInductionRequired":{"type":["boolean","null"]},"checkInRequired":{"type":["boolean","null"]},"autoCheckoutTime":{"type":["string","null"]},"allowWalkIn":{"type":"boolean"},"toolboxRequired":{"type":["boolean","null"]},"toolboxGraceMinutes":{"type":["integer","null"],"minimum":1},"spotterRequired":{"type":["boolean","null"]},"requireDefectPhotos":{"type":["boolean","null"]},"checkValidityHours":{"type":["integer","null"],"minimum":1,"maximum":24,"description":"Deprecated: send checkValidityMinutes. Stored as hours × 60 when checkValidityMinutes is absent; removed in a future release."},"checkValidityMinutes":{"type":["integer","null"],"minimum":1,"maximum":1440},"operatorTimeoutMinutes":{"type":["integer","null"],"minimum":1,"maximum":180},"serviceIntervalHours":{"type":["integer","null"],"minimum":1,"maximum":10000},"serviceIntervalDays":{"type":["integer","null"],"minimum":1,"maximum":3650},"serviceWarningHours":{"type":["integer","null"],"minimum":0,"maximum":1000},"serviceWarningDays":{"type":["integer","null"],"minimum":0,"maximum":365},"preventStartWhenOverdue":{"type":["boolean","null"]},"requirePersonInduction":{"type":"boolean","description":"Pre-start gate: the operator must hold a live grant on this site's roster (be inducted here). Needs the Site Check-In feature: without it the value is stored as false and nothing is enforced."},"requireToolboxAttendance":{"type":"boolean","description":"Pre-start gate: the operator must have attended a toolbox talk at this site within toolboxRecencyHours. Needs the Site Check-In feature: without it the value is stored as false and nothing is enforced."},"toolboxRecencyHours":{"type":"integer","minimum":1},"autoInductContractorEquipment":{"type":"boolean"},"contactName":{"type":["string","null"],"minLength":1,"maxLength":255},"contactPhone":{"type":["string","null"],"minLength":1},"contactEmail":{"type":["string","null"]},"code":{"type":"string"}},"additionalProperties":false,"description":"Update an existing site"}}}},"responses":{"200":{"description":"Site updated","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"code":{"type":["string","null"]},"city":{"type":["string","null"]},"state":{"type":["string","null"]},"latitude":{"type":["number","null"],"minimum":-90,"maximum":90,"description":"WGS-84 latitude in decimal degrees (-90 to 90)"},"longitude":{"type":["number","null"],"minimum":-180,"maximum":180,"description":"WGS-84 longitude in decimal degrees (-180 to 180)"},"radius":{"type":["integer","null"]},"boundaryType":{"type":"string","enum":["CIRCLE","POLYGON"]},"isActive":{"type":"boolean"},"activeDeployments":{"type":"integer"}},"required":["id","name","code","city","state","latitude","longitude","radius","boundaryType","isActive","activeDeployments"],"description":"Site list item response"}},"required":["success","data"],"description":"Standard API success response"}}}}}},"delete":{"operationId":"deleteSite","summary":"Delete site","description":"Soft-deletes a site. Assets deployed to this site are not affected.","tags":["Sites"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"responses":{"204":{"description":"Site deleted"}}}},"/api/v1/defects/export/jobs/{id}":{"get":{"operationId":"getDefectsExportJob","summary":"Get defects export job status","description":"Poll the status of a background export job (returned by GET /export when the row count exceeds 10000). Export files are kept for 30 days; a job past that window returns 404 whether or not the retention sweep has reached it yet.","tags":["Defects"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Export job status","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"jobId":{"type":"string","format":"uuid"},"resource":{"type":"string"},"format":{"type":"string","enum":["csv","xlsx"]},"status":{"type":"string","enum":["PENDING","GENERATING","COMPLETED","FAILED"]},"rowCount":{"type":["integer","null"],"minimum":0},"fileUrl":{"type":["string","null"],"maxLength":2048,"format":"uri"},"fileSize":{"type":["integer","null"],"minimum":0},"errorMessage":{"type":["string","null"],"maxLength":2000},"createdAt":{"type":["string","null"],"format":"date-time"},"updatedAt":{"type":["string","null"],"format":"date-time"},"completedAt":{"type":["string","null"],"format":"date-time"}},"required":["jobId","resource","format","status","createdAt","updatedAt"],"description":"Async resource-export job status"}},"required":["success","data"],"description":"Standard API success response"}}}},"404":{"description":"Export job not found"}}}},"/api/v1/defects/export":{"get":{"operationId":"exportDefects","summary":"Export defects","description":"Download defects as a CSV or XLSX file. Accepts the same filters as the list endpoint (equipmentId, siteId, status, severity, assignedToUserId, from, to, search) so a filtered view exports the filtered set.","tags":["Defects"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","enum":["csv","xlsx"],"default":"csv"},"required":false,"name":"format","in":"query"},{"schema":{"type":"string","maxLength":100},"required":false,"name":"search","in":"query"},{"schema":{"type":"string","format":"uuid"},"required":false,"name":"equipmentId","in":"query"},{"schema":{"type":"string","format":"uuid"},"required":false,"name":"siteId","in":"query"},{"schema":{"type":"string","enum":["REPORTED","ACKNOWLEDGED","RESOLVED","CLOSED","OPEN"],"description":"One defect status, or OPEN for any open status (REPORTED or ACKNOWLEDGED)"},"required":false,"description":"One defect status, or OPEN for any open status (REPORTED or ACKNOWLEDGED)","name":"status","in":"query"},{"schema":{"type":"string","enum":["LOW","MEDIUM","HIGH","CRITICAL"]},"required":false,"name":"severity","in":"query"},{"schema":{"type":"string","enum":["MANUAL","PRESTART_CAPTURE","PRESTART_AUTO","INTEGRATION"]},"required":false,"name":"origin","in":"query"},{"schema":{"type":"string","format":"uuid"},"required":false,"name":"assignedToUserId","in":"query"},{"schema":{"type":["string","null"],"format":"date-time"},"required":false,"name":"from","in":"query"},{"schema":{"type":["string","null"],"format":"date-time"},"required":false,"name":"to","in":"query"}],"responses":{"200":{"description":"File download","content":{"application/octet-stream":{"schema":{"type":"string"}}}},"202":{"description":"Row count exceeds the 10000-row inline limit — generation queued as a background job. Retain `data.jobId` and poll `GET /api/v1/defects/export/jobs/{jobId}` until `status` is `COMPLETED`, then download `fileUrl` (a short-lived signed URL, re-signed on each poll). Completion is not announced by any other channel.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"jobId":{"type":"string","format":"uuid"},"resource":{"type":"string"},"format":{"type":"string","enum":["csv","xlsx"]},"status":{"type":"string","enum":["PENDING","GENERATING","COMPLETED","FAILED"]},"rowCount":{"type":["integer","null"],"minimum":0},"fileUrl":{"type":["string","null"],"maxLength":2048,"format":"uri"},"fileSize":{"type":["integer","null"],"minimum":0},"errorMessage":{"type":["string","null"],"maxLength":2000},"createdAt":{"type":["string","null"],"format":"date-time"},"updatedAt":{"type":["string","null"],"format":"date-time"},"completedAt":{"type":["string","null"],"format":"date-time"}},"required":["jobId","resource","format","status","createdAt","updatedAt"],"description":"Async resource-export job status"}},"required":["success","data"],"description":"Standard API success response"}}}}}}},"/api/v1/defects/matching-ids":{"get":{"operationId":"getMatchingDefectIds","summary":"Get ids of all defects matching a filter set","description":"Returns every defect id matching the given filters (up to a bounded cap), for the \"select all N matching filters\" bulk-action flow. Accepts the same filters as the list endpoint, minus pagination.","tags":["Defects"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","maxLength":100},"required":false,"name":"search","in":"query"},{"schema":{"type":"string","format":"uuid"},"required":false,"name":"equipmentId","in":"query"},{"schema":{"type":"string","format":"uuid"},"required":false,"name":"siteId","in":"query"},{"schema":{"type":"string","enum":["REPORTED","ACKNOWLEDGED","RESOLVED","CLOSED","OPEN"],"description":"One defect status, or OPEN for any open status (REPORTED or ACKNOWLEDGED)"},"required":false,"description":"One defect status, or OPEN for any open status (REPORTED or ACKNOWLEDGED)","name":"status","in":"query"},{"schema":{"type":"string","enum":["LOW","MEDIUM","HIGH","CRITICAL"]},"required":false,"name":"severity","in":"query"},{"schema":{"type":"string","enum":["MANUAL","PRESTART_CAPTURE","PRESTART_AUTO","INTEGRATION"]},"required":false,"name":"origin","in":"query"},{"schema":{"type":"string","format":"uuid"},"required":false,"name":"assignedToUserId","in":"query"},{"schema":{"type":["string","null"],"format":"date-time"},"required":false,"name":"from","in":"query"},{"schema":{"type":["string","null"],"format":"date-time"},"required":false,"name":"to","in":"query"}],"responses":{"200":{"description":"Matching defect ids","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"ids":{"type":"array","items":{"type":"string","format":"uuid"}},"truncated":{"type":"boolean"}},"required":["ids","truncated"],"description":"Ids of all defects matching a filter set, capped at MAX_MATCHING_IDS"}},"required":["success","data"],"description":"Standard API success response"}}}}}}},"/api/v1/defects/:id/document":{"get":{"operationId":"getDefectDocument","summary":"Download defect PDF document","description":"Renders a branded PDF for a single defect — header, description, photos, comments, and the full status-transition timeline.","tags":["Defects"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"PDF document","content":{"application/pdf":{"schema":{"type":"string"}}}},"404":{"description":"Defect not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}}},"/api/v1/defects/:id/document/email":{"post":{"operationId":"emailDefectDocument","summary":"Email defect PDF document","description":"Renders the defect PDF document and emails it to the given recipients.","tags":["Defects"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"recipients":{"type":"array","items":{"type":"string"},"minItems":1,"maxItems":50}},"required":["recipients"],"additionalProperties":false,"description":"Email the defect document PDF to the given recipients"}}}},"responses":{"200":{"description":"Document emailed","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"sent":{"type":"number"}},"required":["sent"]}},"required":["success","data"],"description":"Standard API success response"}}}},"404":{"description":"Defect not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}}},"/api/v1/defects":{"get":{"operationId":"listDefects","summary":"List defects","description":"Returns a paginated list of asset defects for the authenticated org. Supports filtering by asset, status, and severity.","tags":["Defects"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","maxLength":500},"required":false,"name":"after","in":"query"},{"schema":{"type":"string","maxLength":100},"required":false,"name":"search","in":"query"},{"schema":{"type":"string","format":"uuid"},"required":false,"name":"equipmentId","in":"query"},{"schema":{"type":"string","format":"uuid"},"required":false,"name":"siteId","in":"query"},{"schema":{"type":"string","enum":["REPORTED","ACKNOWLEDGED","RESOLVED","CLOSED","OPEN"],"description":"One defect status, or OPEN for any open status (REPORTED or ACKNOWLEDGED)"},"required":false,"description":"One defect status, or OPEN for any open status (REPORTED or ACKNOWLEDGED)","name":"status","in":"query"},{"schema":{"type":"string","enum":["LOW","MEDIUM","HIGH","CRITICAL"]},"required":false,"name":"severity","in":"query"},{"schema":{"type":"string","enum":["MANUAL","PRESTART_CAPTURE","PRESTART_AUTO","INTEGRATION"]},"required":false,"name":"origin","in":"query"},{"schema":{"type":"string","format":"uuid"},"required":false,"name":"assignedToUserId","in":"query"},{"schema":{"type":["string","null"],"format":"date-time"},"required":false,"name":"from","in":"query"},{"schema":{"type":["string","null"],"format":"date-time"},"required":false,"name":"to","in":"query"}],"responses":{"200":{"description":"List of defects","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"title":{"type":"string"},"description":{"type":"string"},"severity":{"type":"string","enum":["LOW","MEDIUM","HIGH","CRITICAL"]},"status":{"type":"string","enum":["REPORTED","ACKNOWLEDGED","RESOLVED","CLOSED"]},"category":{"type":["string","null"],"enum":["BODY","ENGINE","ELECTRICAL","HYDRAULICS","BRAKES","STEERING","TYRES","SAFETY","FLUIDS","OTHER",null]},"raisedAt":{"type":"string","format":"date-time"},"raisedBy":{"type":"object","properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"User who raised the defect"},"equipment":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"}},"required":["id","name"],"description":"Equipment with the defect"},"commentsCount":{"type":"integer"},"scanSource":{"type":["string","null"],"enum":["qr","nfc","serial",null],"description":"How the user reached the equipment-anchored action: QR scan, NFC tap, or manual serial entry."},"blocksOperation":{"type":"boolean"},"origin":{"type":["string","null"],"enum":["MANUAL","PRESTART_CAPTURE","PRESTART_AUTO","INTEGRATION",null],"description":"How the defect came to exist: MANUAL (raised by hand), PRESTART_CAPTURE (recorded by the operator during a pre-start), PRESTART_AUTO (raised by PreStartGo for a failed pre-start item the operator recorded no defect for), or INTEGRATION (imported). Null for a defect raised before this was recorded."},"blocksOperationSource":{"type":["string","null"],"enum":["SYSTEM","MANUAL",null],"description":"Who set the out-of-service lockout, while blocksOperation is true: SYSTEM (a failed critical pre-start item; closing the defect lifts it) or MANUAL (a technician; only lifting it by hand clears it). Null when blocksOperation is false."}},"required":["id","title","description","severity","status","category","raisedAt","raisedBy","equipment","commentsCount","blocksOperation"],"description":"Defect list item response"}},"meta":{"type":"object","properties":{"limit":{"type":"number"},"hasMore":{"type":"boolean"},"nextCursor":{"type":["string","null"]},"server_time":{"type":"integer"}},"required":["limit","hasMore","nextCursor"]}},"required":["success","data","meta"],"description":"Cursor-paginated API success response","example":{"success":true,"data":[{"id":"e5f6a7b8-0000-4000-a000-000000000004","title":"Hydraulic leak — boom cylinder","description":"Oil weeping from the boom cylinder rod seal; drips under the machine.","severity":"HIGH","status":"REPORTED","category":"HYDRAULICS","raisedAt":"2025-04-20T06:05:00.000Z","raisedBy":{"userId":"c2d3e4f5-0000-4000-a000-000000000002","name":"Jordan Referee","nameSource":"PERSON","email":null,"phone":null},"equipment":{"id":"a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11","name":"Cat 320 Excavator"},"commentsCount":0,"scanSource":"qr","blocksOperation":false}],"meta":{"limit":20,"hasMore":false,"nextCursor":null}}}}}}}},"post":{"operationId":"createDefect","summary":"Create defect","description":"Reports a new defect against equipment. equipmentId and category are required.","tags":["Defects"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"equipmentId":{"type":"string","format":"uuid"},"checkId":{"type":"string","format":"uuid"},"checklistItemId":{"type":"string","format":"uuid"},"localId":{"type":"string","maxLength":100},"title":{"type":"string","minLength":1,"maxLength":255},"description":{"type":"string","maxLength":2000},"notes":{"type":"string","maxLength":2000},"severity":{"type":"string","enum":["LOW","MEDIUM","HIGH","CRITICAL"],"default":"MEDIUM"},"category":{"type":"string","enum":["BODY","ENGINE","ELECTRICAL","HYDRAULICS","BRAKES","STEERING","TYRES","SAFETY","FLUIDS","OTHER"]},"raisedAt":{"type":"string","format":"date-time"},"raisedLatitude":{"type":["number","null"],"minimum":-90,"maximum":90,"description":"WGS-84 latitude in decimal degrees (-90 to 90)"},"raisedLongitude":{"type":["number","null"],"minimum":-180,"maximum":180,"description":"WGS-84 longitude in decimal degrees (-180 to 180)"},"scanSource":{"type":["string","null"],"enum":["qr","nfc","serial",null],"description":"How the user reached the equipment-anchored action: QR scan, NFC tap, or manual serial entry."}},"required":["equipmentId","title","description","category"],"additionalProperties":false,"description":"Report a new defect on an equipment"}}}},"responses":{"201":{"description":"Defect created","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"title":{"type":"string"},"description":{"type":"string"},"severity":{"type":"string","enum":["LOW","MEDIUM","HIGH","CRITICAL"]},"status":{"type":"string","enum":["REPORTED","ACKNOWLEDGED","RESOLVED","CLOSED"]},"category":{"type":["string","null"],"enum":["BODY","ENGINE","ELECTRICAL","HYDRAULICS","BRAKES","STEERING","TYRES","SAFETY","FLUIDS","OTHER",null]},"raisedAt":{"type":"string","format":"date-time"},"raisedBy":{"type":"object","properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"User who raised the defect"},"equipment":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"}},"required":["id","name"],"description":"Equipment with the defect"},"commentsCount":{"type":"integer"},"scanSource":{"type":["string","null"],"enum":["qr","nfc","serial",null],"description":"How the user reached the equipment-anchored action: QR scan, NFC tap, or manual serial entry."},"blocksOperation":{"type":"boolean"},"origin":{"type":["string","null"],"enum":["MANUAL","PRESTART_CAPTURE","PRESTART_AUTO","INTEGRATION",null],"description":"How the defect came to exist: MANUAL (raised by hand), PRESTART_CAPTURE (recorded by the operator during a pre-start), PRESTART_AUTO (raised by PreStartGo for a failed pre-start item the operator recorded no defect for), or INTEGRATION (imported). Null for a defect raised before this was recorded."},"blocksOperationSource":{"type":["string","null"],"enum":["SYSTEM","MANUAL",null],"description":"Who set the out-of-service lockout, while blocksOperation is true: SYSTEM (a failed critical pre-start item; closing the defect lifts it) or MANUAL (a technician; only lifting it by hand clears it). Null when blocksOperation is false."},"notes":{"type":["string","null"]},"assignedToUserId":{"type":["string","null"],"format":"uuid"},"assignedTo":{"type":["object","null"],"properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"Who the defect is assigned to"},"assignedToExternal":{"type":["string","null"]},"externalReferenceId":{"type":["string","null"]},"raisedLatitude":{"type":["number","null"],"minimum":-90,"maximum":90,"description":"WGS-84 latitude in decimal degrees (-90 to 90)"},"raisedLongitude":{"type":["number","null"],"minimum":-180,"maximum":180,"description":"WGS-84 longitude in decimal degrees (-180 to 180)"},"fixedAt":{"type":["string","null"],"format":"date-time"},"fixedBy":{"type":["object","null"],"properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"User who resolved the defect"},"fixedNotes":{"type":["string","null"]},"withdrawnAt":{"type":["string","null"],"format":"date-time"},"check":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid"},"performedAt":{"type":"string","format":"date-time"}},"required":["id","performedAt"],"description":"Originating pre-start check"},"photos":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"fileUrl":{"type":"string","maxLength":2048,"format":"uri"},"mimeType":{"type":"string","maxLength":100},"fileSize":{"type":"integer","minimum":0},"uploadedBy":{"type":"object","properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"User who uploaded the photo"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","fileUrl","mimeType","fileSize","uploadedBy","createdAt"],"description":"Defect photo"}},"comments":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"content":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"user":{"type":"object","properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"Comment author"},"userAvatarUrl":{"type":["string","null"],"maxLength":2048,"format":"uri"}},"required":["id","content","createdAt","user","userAvatarUrl"],"description":"Defect comment"}},"transitions":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"fromStatus":{"type":"string","enum":["REPORTED","ACKNOWLEDGED","RESOLVED","CLOSED"]},"toStatus":{"type":"string","enum":["REPORTED","ACKNOWLEDGED","RESOLVED","CLOSED"]},"userId":{"type":"string","format":"uuid"},"notes":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"}},"required":["id","fromStatus","toStatus","userId","notes","createdAt"],"description":"Defect status transition"}}},"required":["id","title","description","severity","status","category","raisedAt","raisedBy","equipment","commentsCount","blocksOperation","notes","assignedToUserId","assignedTo","assignedToExternal","externalReferenceId","raisedLatitude","raisedLongitude","fixedAt","fixedBy","fixedNotes","withdrawnAt","check","photos","comments"],"description":"Defect detail response"}},"required":["success","data"],"description":"Standard API success response"}}}}}}},"/api/v1/defects/:id":{"get":{"operationId":"getDefect","summary":"Get defect","description":"Returns full details of a defect, including the associated asset/site, photos, and check information.","tags":["Defects"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Defect details","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"title":{"type":"string"},"description":{"type":"string"},"severity":{"type":"string","enum":["LOW","MEDIUM","HIGH","CRITICAL"]},"status":{"type":"string","enum":["REPORTED","ACKNOWLEDGED","RESOLVED","CLOSED"]},"category":{"type":["string","null"],"enum":["BODY","ENGINE","ELECTRICAL","HYDRAULICS","BRAKES","STEERING","TYRES","SAFETY","FLUIDS","OTHER",null]},"raisedAt":{"type":"string","format":"date-time"},"raisedBy":{"type":"object","properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"User who raised the defect"},"equipment":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"}},"required":["id","name"],"description":"Equipment with the defect"},"commentsCount":{"type":"integer"},"scanSource":{"type":["string","null"],"enum":["qr","nfc","serial",null],"description":"How the user reached the equipment-anchored action: QR scan, NFC tap, or manual serial entry."},"blocksOperation":{"type":"boolean"},"origin":{"type":["string","null"],"enum":["MANUAL","PRESTART_CAPTURE","PRESTART_AUTO","INTEGRATION",null],"description":"How the defect came to exist: MANUAL (raised by hand), PRESTART_CAPTURE (recorded by the operator during a pre-start), PRESTART_AUTO (raised by PreStartGo for a failed pre-start item the operator recorded no defect for), or INTEGRATION (imported). Null for a defect raised before this was recorded."},"blocksOperationSource":{"type":["string","null"],"enum":["SYSTEM","MANUAL",null],"description":"Who set the out-of-service lockout, while blocksOperation is true: SYSTEM (a failed critical pre-start item; closing the defect lifts it) or MANUAL (a technician; only lifting it by hand clears it). Null when blocksOperation is false."},"notes":{"type":["string","null"]},"assignedToUserId":{"type":["string","null"],"format":"uuid"},"assignedTo":{"type":["object","null"],"properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"Who the defect is assigned to"},"assignedToExternal":{"type":["string","null"]},"externalReferenceId":{"type":["string","null"]},"raisedLatitude":{"type":["number","null"],"minimum":-90,"maximum":90,"description":"WGS-84 latitude in decimal degrees (-90 to 90)"},"raisedLongitude":{"type":["number","null"],"minimum":-180,"maximum":180,"description":"WGS-84 longitude in decimal degrees (-180 to 180)"},"fixedAt":{"type":["string","null"],"format":"date-time"},"fixedBy":{"type":["object","null"],"properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"User who resolved the defect"},"fixedNotes":{"type":["string","null"]},"withdrawnAt":{"type":["string","null"],"format":"date-time"},"check":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid"},"performedAt":{"type":"string","format":"date-time"}},"required":["id","performedAt"],"description":"Originating pre-start check"},"photos":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"fileUrl":{"type":"string","maxLength":2048,"format":"uri"},"mimeType":{"type":"string","maxLength":100},"fileSize":{"type":"integer","minimum":0},"uploadedBy":{"type":"object","properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"User who uploaded the photo"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","fileUrl","mimeType","fileSize","uploadedBy","createdAt"],"description":"Defect photo"}},"comments":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"content":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"user":{"type":"object","properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"Comment author"},"userAvatarUrl":{"type":["string","null"],"maxLength":2048,"format":"uri"}},"required":["id","content","createdAt","user","userAvatarUrl"],"description":"Defect comment"}},"transitions":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"fromStatus":{"type":"string","enum":["REPORTED","ACKNOWLEDGED","RESOLVED","CLOSED"]},"toStatus":{"type":"string","enum":["REPORTED","ACKNOWLEDGED","RESOLVED","CLOSED"]},"userId":{"type":"string","format":"uuid"},"notes":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"}},"required":["id","fromStatus","toStatus","userId","notes","createdAt"],"description":"Defect status transition"}}},"required":["id","title","description","severity","status","category","raisedAt","raisedBy","equipment","commentsCount","blocksOperation","notes","assignedToUserId","assignedTo","assignedToExternal","externalReferenceId","raisedLatitude","raisedLongitude","fixedAt","fixedBy","fixedNotes","withdrawnAt","check","photos","comments"],"description":"Defect detail response"}},"required":["success","data"],"description":"Standard API success response"}}}},"404":{"description":"Defect not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}},"patch":{"operationId":"updateDefect","summary":"Update defect","description":"Updates defect details such as severity, description, or assigned technician.","tags":["Defects"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":255},"description":{"type":"string","maxLength":2000},"severity":{"type":"string","enum":["LOW","MEDIUM","HIGH","CRITICAL"]},"category":{"type":"string","enum":["BODY","ENGINE","ELECTRICAL","HYDRAULICS","BRAKES","STEERING","TYRES","SAFETY","FLUIDS","OTHER"]},"notes":{"type":"string","maxLength":2000},"assignedToUserId":{"type":["string","null"],"format":"uuid"},"assignedToExternal":{"type":["string","null"],"minLength":1,"maxLength":255},"externalReferenceId":{"type":["string","null"],"maxLength":100}},"additionalProperties":false,"description":"Update an existing defect"}}}},"responses":{"200":{"description":"Defect updated","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"title":{"type":"string"},"description":{"type":"string"},"severity":{"type":"string","enum":["LOW","MEDIUM","HIGH","CRITICAL"]},"status":{"type":"string","enum":["REPORTED","ACKNOWLEDGED","RESOLVED","CLOSED"]},"category":{"type":["string","null"],"enum":["BODY","ENGINE","ELECTRICAL","HYDRAULICS","BRAKES","STEERING","TYRES","SAFETY","FLUIDS","OTHER",null]},"raisedAt":{"type":"string","format":"date-time"},"raisedBy":{"type":"object","properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"User who raised the defect"},"equipment":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"}},"required":["id","name"],"description":"Equipment with the defect"},"commentsCount":{"type":"integer"},"scanSource":{"type":["string","null"],"enum":["qr","nfc","serial",null],"description":"How the user reached the equipment-anchored action: QR scan, NFC tap, or manual serial entry."},"blocksOperation":{"type":"boolean"},"origin":{"type":["string","null"],"enum":["MANUAL","PRESTART_CAPTURE","PRESTART_AUTO","INTEGRATION",null],"description":"How the defect came to exist: MANUAL (raised by hand), PRESTART_CAPTURE (recorded by the operator during a pre-start), PRESTART_AUTO (raised by PreStartGo for a failed pre-start item the operator recorded no defect for), or INTEGRATION (imported). Null for a defect raised before this was recorded."},"blocksOperationSource":{"type":["string","null"],"enum":["SYSTEM","MANUAL",null],"description":"Who set the out-of-service lockout, while blocksOperation is true: SYSTEM (a failed critical pre-start item; closing the defect lifts it) or MANUAL (a technician; only lifting it by hand clears it). Null when blocksOperation is false."},"notes":{"type":["string","null"]},"assignedToUserId":{"type":["string","null"],"format":"uuid"},"assignedTo":{"type":["object","null"],"properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"Who the defect is assigned to"},"assignedToExternal":{"type":["string","null"]},"externalReferenceId":{"type":["string","null"]},"raisedLatitude":{"type":["number","null"],"minimum":-90,"maximum":90,"description":"WGS-84 latitude in decimal degrees (-90 to 90)"},"raisedLongitude":{"type":["number","null"],"minimum":-180,"maximum":180,"description":"WGS-84 longitude in decimal degrees (-180 to 180)"},"fixedAt":{"type":["string","null"],"format":"date-time"},"fixedBy":{"type":["object","null"],"properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"User who resolved the defect"},"fixedNotes":{"type":["string","null"]},"withdrawnAt":{"type":["string","null"],"format":"date-time"},"check":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid"},"performedAt":{"type":"string","format":"date-time"}},"required":["id","performedAt"],"description":"Originating pre-start check"},"photos":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"fileUrl":{"type":"string","maxLength":2048,"format":"uri"},"mimeType":{"type":"string","maxLength":100},"fileSize":{"type":"integer","minimum":0},"uploadedBy":{"type":"object","properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"User who uploaded the photo"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","fileUrl","mimeType","fileSize","uploadedBy","createdAt"],"description":"Defect photo"}},"comments":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"content":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"user":{"type":"object","properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"Comment author"},"userAvatarUrl":{"type":["string","null"],"maxLength":2048,"format":"uri"}},"required":["id","content","createdAt","user","userAvatarUrl"],"description":"Defect comment"}},"transitions":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"fromStatus":{"type":"string","enum":["REPORTED","ACKNOWLEDGED","RESOLVED","CLOSED"]},"toStatus":{"type":"string","enum":["REPORTED","ACKNOWLEDGED","RESOLVED","CLOSED"]},"userId":{"type":"string","format":"uuid"},"notes":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"}},"required":["id","fromStatus","toStatus","userId","notes","createdAt"],"description":"Defect status transition"}}},"required":["id","title","description","severity","status","category","raisedAt","raisedBy","equipment","commentsCount","blocksOperation","notes","assignedToUserId","assignedTo","assignedToExternal","externalReferenceId","raisedLatitude","raisedLongitude","fixedAt","fixedBy","fixedNotes","withdrawnAt","check","photos","comments"],"description":"Defect detail response"}},"required":["success","data"],"description":"Standard API success response"}}}}}},"delete":{"operationId":"deleteDefect","summary":"Delete defect (soft-delete)","description":"Soft-deletes a defect. The defect record is retained for audit purposes.","tags":["Defects"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"responses":{"204":{"description":"Defect deleted"},"404":{"description":"Defect not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}},"409":{"description":"The defect is holding its equipment out of service (`blocksOperation`), so it cannot be deleted: `error.messageKey` is `defect.delete_blocks_operation`. Lift the lockout (or close the defect, which lifts a lockout a failed critical pre-start item set) first.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}}},"/api/v1/defects/:id/resolve":{"post":{"operationId":"resolveDefect","summary":"Resolve defect","description":"Marks a defect as resolved with resolution notes. Creates an audit trail entry for the defect transition.","tags":["Defects"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"notes":{"type":"string","maxLength":2000}},"required":["notes"],"additionalProperties":false,"description":"Resolve a defect with notes"}}}},"responses":{"200":{"description":"Defect resolved","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"title":{"type":"string"},"description":{"type":"string"},"severity":{"type":"string","enum":["LOW","MEDIUM","HIGH","CRITICAL"]},"status":{"type":"string","enum":["REPORTED","ACKNOWLEDGED","RESOLVED","CLOSED"]},"category":{"type":["string","null"],"enum":["BODY","ENGINE","ELECTRICAL","HYDRAULICS","BRAKES","STEERING","TYRES","SAFETY","FLUIDS","OTHER",null]},"raisedAt":{"type":"string","format":"date-time"},"raisedBy":{"type":"object","properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"User who raised the defect"},"equipment":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"}},"required":["id","name"],"description":"Equipment with the defect"},"commentsCount":{"type":"integer"},"scanSource":{"type":["string","null"],"enum":["qr","nfc","serial",null],"description":"How the user reached the equipment-anchored action: QR scan, NFC tap, or manual serial entry."},"blocksOperation":{"type":"boolean"},"origin":{"type":["string","null"],"enum":["MANUAL","PRESTART_CAPTURE","PRESTART_AUTO","INTEGRATION",null],"description":"How the defect came to exist: MANUAL (raised by hand), PRESTART_CAPTURE (recorded by the operator during a pre-start), PRESTART_AUTO (raised by PreStartGo for a failed pre-start item the operator recorded no defect for), or INTEGRATION (imported). Null for a defect raised before this was recorded."},"blocksOperationSource":{"type":["string","null"],"enum":["SYSTEM","MANUAL",null],"description":"Who set the out-of-service lockout, while blocksOperation is true: SYSTEM (a failed critical pre-start item; closing the defect lifts it) or MANUAL (a technician; only lifting it by hand clears it). Null when blocksOperation is false."},"notes":{"type":["string","null"]},"assignedToUserId":{"type":["string","null"],"format":"uuid"},"assignedTo":{"type":["object","null"],"properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"Who the defect is assigned to"},"assignedToExternal":{"type":["string","null"]},"externalReferenceId":{"type":["string","null"]},"raisedLatitude":{"type":["number","null"],"minimum":-90,"maximum":90,"description":"WGS-84 latitude in decimal degrees (-90 to 90)"},"raisedLongitude":{"type":["number","null"],"minimum":-180,"maximum":180,"description":"WGS-84 longitude in decimal degrees (-180 to 180)"},"fixedAt":{"type":["string","null"],"format":"date-time"},"fixedBy":{"type":["object","null"],"properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"User who resolved the defect"},"fixedNotes":{"type":["string","null"]},"withdrawnAt":{"type":["string","null"],"format":"date-time"},"check":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid"},"performedAt":{"type":"string","format":"date-time"}},"required":["id","performedAt"],"description":"Originating pre-start check"},"photos":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"fileUrl":{"type":"string","maxLength":2048,"format":"uri"},"mimeType":{"type":"string","maxLength":100},"fileSize":{"type":"integer","minimum":0},"uploadedBy":{"type":"object","properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"User who uploaded the photo"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","fileUrl","mimeType","fileSize","uploadedBy","createdAt"],"description":"Defect photo"}},"comments":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"content":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"user":{"type":"object","properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"Comment author"},"userAvatarUrl":{"type":["string","null"],"maxLength":2048,"format":"uri"}},"required":["id","content","createdAt","user","userAvatarUrl"],"description":"Defect comment"}},"transitions":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"fromStatus":{"type":"string","enum":["REPORTED","ACKNOWLEDGED","RESOLVED","CLOSED"]},"toStatus":{"type":"string","enum":["REPORTED","ACKNOWLEDGED","RESOLVED","CLOSED"]},"userId":{"type":"string","format":"uuid"},"notes":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"}},"required":["id","fromStatus","toStatus","userId","notes","createdAt"],"description":"Defect status transition"}}},"required":["id","title","description","severity","status","category","raisedAt","raisedBy","equipment","commentsCount","blocksOperation","notes","assignedToUserId","assignedTo","assignedToExternal","externalReferenceId","raisedLatitude","raisedLongitude","fixedAt","fixedBy","fixedNotes","withdrawnAt","check","photos","comments"],"description":"Defect detail response"}},"required":["success","data"],"description":"Standard API success response"}}}}}}},"/api/v1/defects/:id/transition":{"post":{"operationId":"transitionDefect","summary":"Transition defect status","description":"Advances a defect to a new status in the workflow. Each transition is validated against the state machine and recorded in the audit trail. Per-transition RBAC is enforced in the service layer.","tags":["Defects"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"toStatus":{"type":"string","enum":["REPORTED","ACKNOWLEDGED","RESOLVED","CLOSED"]},"notes":{"type":"string","maxLength":2000}},"required":["toStatus"],"additionalProperties":false,"description":"Transition a defect status"}}}},"responses":{"200":{"description":"Defect transitioned","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"title":{"type":"string"},"description":{"type":"string"},"severity":{"type":"string","enum":["LOW","MEDIUM","HIGH","CRITICAL"]},"status":{"type":"string","enum":["REPORTED","ACKNOWLEDGED","RESOLVED","CLOSED"]},"category":{"type":["string","null"],"enum":["BODY","ENGINE","ELECTRICAL","HYDRAULICS","BRAKES","STEERING","TYRES","SAFETY","FLUIDS","OTHER",null]},"raisedAt":{"type":"string","format":"date-time"},"raisedBy":{"type":"object","properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"User who raised the defect"},"equipment":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"}},"required":["id","name"],"description":"Equipment with the defect"},"commentsCount":{"type":"integer"},"scanSource":{"type":["string","null"],"enum":["qr","nfc","serial",null],"description":"How the user reached the equipment-anchored action: QR scan, NFC tap, or manual serial entry."},"blocksOperation":{"type":"boolean"},"origin":{"type":["string","null"],"enum":["MANUAL","PRESTART_CAPTURE","PRESTART_AUTO","INTEGRATION",null],"description":"How the defect came to exist: MANUAL (raised by hand), PRESTART_CAPTURE (recorded by the operator during a pre-start), PRESTART_AUTO (raised by PreStartGo for a failed pre-start item the operator recorded no defect for), or INTEGRATION (imported). Null for a defect raised before this was recorded."},"blocksOperationSource":{"type":["string","null"],"enum":["SYSTEM","MANUAL",null],"description":"Who set the out-of-service lockout, while blocksOperation is true: SYSTEM (a failed critical pre-start item; closing the defect lifts it) or MANUAL (a technician; only lifting it by hand clears it). Null when blocksOperation is false."},"notes":{"type":["string","null"]},"assignedToUserId":{"type":["string","null"],"format":"uuid"},"assignedTo":{"type":["object","null"],"properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"Who the defect is assigned to"},"assignedToExternal":{"type":["string","null"]},"externalReferenceId":{"type":["string","null"]},"raisedLatitude":{"type":["number","null"],"minimum":-90,"maximum":90,"description":"WGS-84 latitude in decimal degrees (-90 to 90)"},"raisedLongitude":{"type":["number","null"],"minimum":-180,"maximum":180,"description":"WGS-84 longitude in decimal degrees (-180 to 180)"},"fixedAt":{"type":["string","null"],"format":"date-time"},"fixedBy":{"type":["object","null"],"properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"User who resolved the defect"},"fixedNotes":{"type":["string","null"]},"withdrawnAt":{"type":["string","null"],"format":"date-time"},"check":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid"},"performedAt":{"type":"string","format":"date-time"}},"required":["id","performedAt"],"description":"Originating pre-start check"},"photos":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"fileUrl":{"type":"string","maxLength":2048,"format":"uri"},"mimeType":{"type":"string","maxLength":100},"fileSize":{"type":"integer","minimum":0},"uploadedBy":{"type":"object","properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"User who uploaded the photo"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","fileUrl","mimeType","fileSize","uploadedBy","createdAt"],"description":"Defect photo"}},"comments":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"content":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"user":{"type":"object","properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"Comment author"},"userAvatarUrl":{"type":["string","null"],"maxLength":2048,"format":"uri"}},"required":["id","content","createdAt","user","userAvatarUrl"],"description":"Defect comment"}},"transitions":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"fromStatus":{"type":"string","enum":["REPORTED","ACKNOWLEDGED","RESOLVED","CLOSED"]},"toStatus":{"type":"string","enum":["REPORTED","ACKNOWLEDGED","RESOLVED","CLOSED"]},"userId":{"type":"string","format":"uuid"},"notes":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"}},"required":["id","fromStatus","toStatus","userId","notes","createdAt"],"description":"Defect status transition"}}},"required":["id","title","description","severity","status","category","raisedAt","raisedBy","equipment","commentsCount","blocksOperation","notes","assignedToUserId","assignedTo","assignedToExternal","externalReferenceId","raisedLatitude","raisedLongitude","fixedAt","fixedBy","fixedNotes","withdrawnAt","check","photos","comments"],"description":"Defect detail response"}},"required":["success","data"],"description":"Standard API success response"}}}},"404":{"description":"Defect not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}}},"/api/v1/defects/:id/photos":{"post":{"operationId":"createDefectPhoto","summary":"Add photo to defect","description":"Attaches a photo to a defect. The photo file should already be uploaded via the uploads endpoint.","tags":["Defects"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"fileUrl":{"type":"string","maxLength":2048,"format":"uri"},"mimeType":{"type":"string","enum":["image/jpeg","image/png","image/webp","image/gif","image/heic","image/heif","application/pdf","text/csv","application/vnd.openxmlformats-officedocument.spreadsheetml.sheet","application/vnd.ms-excel"],"description":"Allowed MIME types for file uploads"},"fileSize":{"type":"integer","minimum":0,"maximum":52428800},"localId":{"type":"string","maxLength":100}},"required":["fileUrl","mimeType","fileSize"],"additionalProperties":false,"description":"Attach a photo to a defect"}}}},"responses":{"201":{"description":"Photo attached to defect","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"fileUrl":{"type":"string","maxLength":2048,"format":"uri"},"mimeType":{"type":"string","maxLength":100},"fileSize":{"type":"integer","minimum":0},"uploadedBy":{"type":"object","properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"A person: the name this org shows for them, where that name came from, and the contact that tells two same-named people apart"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","fileUrl","mimeType","fileSize","uploadedBy","createdAt"],"description":"Defect photo response with uploader info"}},"required":["success","data"],"description":"Standard API success response"}}}},"404":{"description":"Defect not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}},"get":{"operationId":"listDefectPhotos","summary":"List defect photos","description":"Returns all photos attached to a defect.","tags":["Defects"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"List of defect photos","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"fileUrl":{"type":"string","maxLength":2048,"format":"uri"},"mimeType":{"type":"string","maxLength":100},"fileSize":{"type":"integer","minimum":0},"uploadedBy":{"type":"object","properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"A person: the name this org shows for them, where that name came from, and the contact that tells two same-named people apart"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","fileUrl","mimeType","fileSize","uploadedBy","createdAt"],"description":"Defect photo response with uploader info"}}},"required":["success","data"],"description":"Standard API success response"}}}},"404":{"description":"Defect not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}}},"/api/v1/groups":{"get":{"operationId":"listGroups","summary":"List groups","description":"Returns a paginated list of groups for the authenticated org. Groups organize equipment and users for access control.","tags":["Groups"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","maxLength":500},"required":false,"name":"after","in":"query"},{"schema":{"type":"string","maxLength":100},"required":false,"name":"search","in":"query"}],"responses":{"200":{"description":"List of groups","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"orgId":{"type":"string","format":"uuid"},"name":{"type":"string"},"description":{"type":["string","null"]},"checklistTemplate":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"}},"required":["id","name"],"description":"Default checklist template for this group"},"serviceChecklistTemplate":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"}},"required":["id","name"],"description":"Default SERVICE checklist for a new service on a machine in this group. Null when none. Always sent."},"checkValidityMinutes":{"type":["integer","null"]},"checkValidityHours":{"type":["integer","null"],"description":"Deprecated: use checkValidityMinutes. The pre-start timer rounded down to whole hours, never below 1; removed in a future release."},"spotterRequired":{"type":["boolean","null"]},"operatorTimeoutMinutes":{"type":["integer","null"]},"serviceIntervalHours":{"type":["integer","null"]},"serviceIntervalDays":{"type":["integer","null"]},"serviceWarningHours":{"type":["integer","null"]},"serviceWarningDays":{"type":["integer","null"]},"preventStartWhenOverdue":{"type":["boolean","null"]},"unlockDurationSeconds":{"type":["integer","null"]},"alertOnIgnition":{"type":["boolean","null"]},"deviceCheckValidityMinutes":{"type":["integer","null"]},"deviceOperatorTimeoutMinutes":{"type":["integer","null"]},"bypassButtonEnabled":{"type":["boolean","null"]},"isActive":{"type":"boolean"},"code":{"type":["string","null"]},"requireDefectPhotos":{"type":["boolean","null"]},"equipmentCount":{"type":"integer"},"licenseCount":{"type":"integer"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","orgId","name","description","checklistTemplate","checkValidityMinutes","checkValidityHours","spotterRequired","operatorTimeoutMinutes","serviceIntervalHours","serviceIntervalDays","serviceWarningHours","serviceWarningDays","preventStartWhenOverdue","unlockDurationSeconds","alertOnIgnition","deviceCheckValidityMinutes","deviceOperatorTimeoutMinutes","bypassButtonEnabled","isActive","code","requireDefectPhotos","equipmentCount","licenseCount","createdAt","updatedAt"],"description":"Group list item response"}},"meta":{"type":"object","properties":{"limit":{"type":"number"},"hasMore":{"type":"boolean"},"nextCursor":{"type":["string","null"]},"server_time":{"type":"integer"}},"required":["limit","hasMore","nextCursor"]}},"required":["success","data","meta"],"description":"Cursor-paginated API success response"}}}}}},"post":{"operationId":"createGroup","summary":"Create group","description":"Creates a new group in the org for organizing equipment and users.","tags":["Groups"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":255},"code":{"type":["string","null"],"maxLength":50},"description":{"type":["string","null"],"maxLength":2000},"isActive":{"type":"boolean","default":true},"spotterRequired":{"type":["boolean","null"]},"requireDefectPhotos":{"type":["boolean","null"]},"checkValidityHours":{"type":["integer","null"],"minimum":1,"maximum":24,"description":"Deprecated: send checkValidityMinutes. Stored as hours × 60 when checkValidityMinutes is absent; removed in a future release."},"checkValidityMinutes":{"type":["integer","null"],"minimum":1,"maximum":1440},"operatorTimeoutMinutes":{"type":["integer","null"],"minimum":1,"maximum":180},"serviceIntervalHours":{"type":["integer","null"],"minimum":1,"maximum":10000},"serviceIntervalDays":{"type":["integer","null"],"minimum":1,"maximum":3650},"serviceWarningHours":{"type":["integer","null"],"minimum":0,"maximum":1000},"serviceWarningDays":{"type":["integer","null"],"minimum":0,"maximum":365},"preventStartWhenOverdue":{"type":["boolean","null"]},"defaultChecklistTemplateId":{"type":["string","null"],"format":"uuid"},"defaultServiceChecklistTemplateId":{"type":["string","null"],"format":"uuid","description":"The SERVICE checklist a new service on a machine in this group takes when none is chosen (an active SERVICE template of your organization). The machine's own default service checklist wins."}},"required":["name"],"additionalProperties":false,"description":"Create a new group"}}}},"responses":{"201":{"description":"Group created","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"orgId":{"type":"string","format":"uuid"},"name":{"type":"string"},"description":{"type":["string","null"]},"checklistTemplate":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"}},"required":["id","name"],"description":"Default checklist template for this group"},"serviceChecklistTemplate":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"}},"required":["id","name"],"description":"Default SERVICE checklist for a new service on a machine in this group. Null when none. Always sent."},"checkValidityMinutes":{"type":["integer","null"]},"checkValidityHours":{"type":["integer","null"],"description":"Deprecated: use checkValidityMinutes. The pre-start timer rounded down to whole hours, never below 1; removed in a future release."},"spotterRequired":{"type":["boolean","null"]},"operatorTimeoutMinutes":{"type":["integer","null"]},"serviceIntervalHours":{"type":["integer","null"]},"serviceIntervalDays":{"type":["integer","null"]},"serviceWarningHours":{"type":["integer","null"]},"serviceWarningDays":{"type":["integer","null"]},"preventStartWhenOverdue":{"type":["boolean","null"]},"unlockDurationSeconds":{"type":["integer","null"]},"alertOnIgnition":{"type":["boolean","null"]},"deviceCheckValidityMinutes":{"type":["integer","null"]},"deviceOperatorTimeoutMinutes":{"type":["integer","null"]},"bypassButtonEnabled":{"type":["boolean","null"]},"isActive":{"type":"boolean"},"code":{"type":["string","null"]},"requireDefectPhotos":{"type":["boolean","null"]},"equipmentCount":{"type":"integer"},"licenseCount":{"type":"integer"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"equipment":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"status":{"type":"string","enum":["ACTIVE","INACTIVE","MAINTENANCE","DECOMMISSIONED"]},"lockState":{"type":["string","null"],"enum":["UNREGISTERED","AWAITING_CONFIRM","LOCKED","UNLOCKED","OPERATOR_EXPIRED","SERVICE","BYPASS","ERROR",null]}},"required":["id","name","status","lockState"],"description":"Group equipment"}},"licenses":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"phone":{"type":"string"},"userId":{"type":["string","null"],"format":"uuid"},"userName":{"type":["string","null"]},"holder":{"type":["object","null"],"properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"A person: the name this org shows for them, where that name came from, and the contact that tells two same-named people apart"},"designation":{"type":["string","null"],"enum":["OPERATOR","SUPERVISOR","TECHNICIAN","LEAD",null]},"status":{"type":"string","enum":["PENDING","ACTIVE","REVOKED","EXPIRED","CANCELED"]},"isActive":{"type":"boolean"}},"required":["id","phone","userId","userName","holder","designation","status","isActive"],"description":"Group license"}}},"required":["id","orgId","name","description","checklistTemplate","checkValidityMinutes","checkValidityHours","spotterRequired","operatorTimeoutMinutes","serviceIntervalHours","serviceIntervalDays","serviceWarningHours","serviceWarningDays","preventStartWhenOverdue","unlockDurationSeconds","alertOnIgnition","deviceCheckValidityMinutes","deviceOperatorTimeoutMinutes","bypassButtonEnabled","isActive","code","requireDefectPhotos","equipmentCount","licenseCount","createdAt","updatedAt","equipment","licenses"],"description":"Group detail response"}},"required":["success","data"],"description":"Standard API success response"}}}}}}},"/api/v1/groups/export":{"get":{"operationId":"exportGroups","summary":"Export groups","description":"Download groups as CSV or XLSX file.","tags":["Groups"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","enum":["csv","xlsx"],"default":"csv"},"required":false,"name":"format","in":"query"},{"schema":{"type":"string","maxLength":100},"required":false,"name":"search","in":"query"}],"responses":{"200":{"description":"File download","content":{"application/octet-stream":{"schema":{"type":"string"}}}},"202":{"description":"Row count exceeds 10000 — generation queued as a background job. Retain `data.jobId` and poll `GET /api/v1/groups/export/jobs/{jobId}` until `status` is `COMPLETED`, then download `fileUrl` (a short-lived signed URL, re-signed on each poll). Completion is not announced by any other channel.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"jobId":{"type":"string","format":"uuid"},"resource":{"type":"string"},"format":{"type":"string","enum":["csv","xlsx"]},"status":{"type":"string","enum":["PENDING","GENERATING","COMPLETED","FAILED"]},"rowCount":{"type":["integer","null"],"minimum":0},"fileUrl":{"type":["string","null"],"maxLength":2048,"format":"uri"},"fileSize":{"type":["integer","null"],"minimum":0},"errorMessage":{"type":["string","null"],"maxLength":2000},"createdAt":{"type":["string","null"],"format":"date-time"},"updatedAt":{"type":["string","null"],"format":"date-time"},"completedAt":{"type":["string","null"],"format":"date-time"}},"required":["jobId","resource","format","status","createdAt","updatedAt"],"description":"Async resource-export job status"}},"required":["success","data"],"description":"Standard API success response"}}}}}}},"/api/v1/groups/export/jobs/{id}":{"get":{"operationId":"getGroupsExportJob","summary":"Get groups export job status","description":"Poll the status of a background export job (returned by GET /export when the row count exceeds 10000). Export files are kept for 30 days; a job past that window returns 404 whether or not the retention sweep has reached it yet.","tags":["Groups"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Export job status","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"jobId":{"type":"string","format":"uuid"},"resource":{"type":"string"},"format":{"type":"string","enum":["csv","xlsx"]},"status":{"type":"string","enum":["PENDING","GENERATING","COMPLETED","FAILED"]},"rowCount":{"type":["integer","null"],"minimum":0},"fileUrl":{"type":["string","null"],"maxLength":2048,"format":"uri"},"fileSize":{"type":["integer","null"],"minimum":0},"errorMessage":{"type":["string","null"],"maxLength":2000},"createdAt":{"type":["string","null"],"format":"date-time"},"updatedAt":{"type":["string","null"],"format":"date-time"},"completedAt":{"type":["string","null"],"format":"date-time"}},"required":["jobId","resource","format","status","createdAt","updatedAt"],"description":"Async resource-export job status"}},"required":["success","data"],"description":"Standard API success response"}}}},"404":{"description":"Export job not found"}}}},"/api/v1/groups/export/template":{"get":{"operationId":"exportGroupsTemplate","summary":"Download groups import template","description":"Download an XLSX template with headers, example row, and column descriptions for importing groups.","tags":["Groups"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"XLSX template file","content":{"application/octet-stream":{"schema":{"type":"string"}}}}}}},"/api/v1/groups/import/preview":{"post":{"operationId":"previewGroupsImport","summary":"Preview groups import","description":"Parse and validate a CSV/XLSX file for importing groups. Returns a preview with validation results.","tags":["Groups"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"responses":{"200":{"description":"Import preview with validated rows","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"totalRows":{"type":"integer"},"validRows":{"type":"integer"},"errorRows":{"type":"integer"},"rows":{"type":"array","items":{"type":"object","properties":{"rowNumber":{"type":"integer"},"data":{"type":"object","additionalProperties":{}},"valid":{"type":"boolean"},"errors":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"message":{"type":"string"}},"required":["field","message"],"description":"Field-level import validation error"}}},"required":["rowNumber","data","valid","errors"],"description":"Preview row from parsed import file"}},"columns":{"type":"array","items":{"type":"string"}}},"required":["totalRows","validRows","errorRows","rows","columns"],"description":"Import preview with validated rows"}},"required":["success","data"],"description":"Standard API success response"}}}},"400":{"description":"Invalid file"}}}},"/api/v1/groups/import/commit":{"post":{"operationId":"commitGroupsImport","summary":"Commit groups import","description":"Insert validated groups rows in a single database transaction.","tags":["Groups"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"rows":{"type":"array","items":{"type":"object","additionalProperties":{}},"minItems":1,"maxItems":10000}},"required":["rows"],"additionalProperties":false,"description":"Commit validated import rows"}}}},"responses":{"201":{"description":"Import commit result","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"imported":{"type":"integer"},"resource":{"type":"string"}},"required":["imported","resource"],"description":"Import commit result"}},"required":["success","data"],"description":"Standard API success response"}}}},"422":{"description":"One or more rows failed re-validation at commit time","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["IMPORT_VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":["string","null"]}},"required":["code","message","requestId"]}},"required":["success","error"]}}}}}}},"/api/v1/groups/:id":{"get":{"operationId":"getGroup","summary":"Get group","description":"Returns full details of a single group by ID.","tags":["Groups"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Group details","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"orgId":{"type":"string","format":"uuid"},"name":{"type":"string"},"description":{"type":["string","null"]},"checklistTemplate":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"}},"required":["id","name"],"description":"Default checklist template for this group"},"serviceChecklistTemplate":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"}},"required":["id","name"],"description":"Default SERVICE checklist for a new service on a machine in this group. Null when none. Always sent."},"checkValidityMinutes":{"type":["integer","null"]},"checkValidityHours":{"type":["integer","null"],"description":"Deprecated: use checkValidityMinutes. The pre-start timer rounded down to whole hours, never below 1; removed in a future release."},"spotterRequired":{"type":["boolean","null"]},"operatorTimeoutMinutes":{"type":["integer","null"]},"serviceIntervalHours":{"type":["integer","null"]},"serviceIntervalDays":{"type":["integer","null"]},"serviceWarningHours":{"type":["integer","null"]},"serviceWarningDays":{"type":["integer","null"]},"preventStartWhenOverdue":{"type":["boolean","null"]},"unlockDurationSeconds":{"type":["integer","null"]},"alertOnIgnition":{"type":["boolean","null"]},"deviceCheckValidityMinutes":{"type":["integer","null"]},"deviceOperatorTimeoutMinutes":{"type":["integer","null"]},"bypassButtonEnabled":{"type":["boolean","null"]},"isActive":{"type":"boolean"},"code":{"type":["string","null"]},"requireDefectPhotos":{"type":["boolean","null"]},"equipmentCount":{"type":"integer"},"licenseCount":{"type":"integer"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"equipment":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"status":{"type":"string","enum":["ACTIVE","INACTIVE","MAINTENANCE","DECOMMISSIONED"]},"lockState":{"type":["string","null"],"enum":["UNREGISTERED","AWAITING_CONFIRM","LOCKED","UNLOCKED","OPERATOR_EXPIRED","SERVICE","BYPASS","ERROR",null]}},"required":["id","name","status","lockState"],"description":"Group equipment"}},"licenses":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"phone":{"type":"string"},"userId":{"type":["string","null"],"format":"uuid"},"userName":{"type":["string","null"]},"holder":{"type":["object","null"],"properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"A person: the name this org shows for them, where that name came from, and the contact that tells two same-named people apart"},"designation":{"type":["string","null"],"enum":["OPERATOR","SUPERVISOR","TECHNICIAN","LEAD",null]},"status":{"type":"string","enum":["PENDING","ACTIVE","REVOKED","EXPIRED","CANCELED"]},"isActive":{"type":"boolean"}},"required":["id","phone","userId","userName","holder","designation","status","isActive"],"description":"Group license"}}},"required":["id","orgId","name","description","checklistTemplate","checkValidityMinutes","checkValidityHours","spotterRequired","operatorTimeoutMinutes","serviceIntervalHours","serviceIntervalDays","serviceWarningHours","serviceWarningDays","preventStartWhenOverdue","unlockDurationSeconds","alertOnIgnition","deviceCheckValidityMinutes","deviceOperatorTimeoutMinutes","bypassButtonEnabled","isActive","code","requireDefectPhotos","equipmentCount","licenseCount","createdAt","updatedAt","equipment","licenses"],"description":"Group detail response"}},"required":["success","data"],"description":"Standard API success response"}}}},"404":{"description":"Group not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}},"patch":{"operationId":"updateGroup","summary":"Update group","description":"Updates an existing group's name or configuration.","tags":["Groups"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":255},"code":{"type":["string","null"],"maxLength":50},"description":{"type":["string","null"],"maxLength":2000},"isActive":{"type":"boolean"},"spotterRequired":{"type":["boolean","null"]},"requireDefectPhotos":{"type":["boolean","null"]},"checkValidityHours":{"type":["integer","null"],"minimum":1,"maximum":24,"description":"Deprecated: send checkValidityMinutes. Stored as hours × 60 when checkValidityMinutes is absent; removed in a future release."},"checkValidityMinutes":{"type":["integer","null"],"minimum":1,"maximum":1440},"operatorTimeoutMinutes":{"type":["integer","null"],"minimum":1,"maximum":180},"serviceIntervalHours":{"type":["integer","null"],"minimum":1,"maximum":10000},"serviceIntervalDays":{"type":["integer","null"],"minimum":1,"maximum":3650},"serviceWarningHours":{"type":["integer","null"],"minimum":0,"maximum":1000},"serviceWarningDays":{"type":["integer","null"],"minimum":0,"maximum":365},"preventStartWhenOverdue":{"type":["boolean","null"]},"defaultChecklistTemplateId":{"type":["string","null"],"format":"uuid"},"defaultServiceChecklistTemplateId":{"type":["string","null"],"format":"uuid","description":"The SERVICE checklist a new service on a machine in this group takes when none is chosen (an active SERVICE template of your organization). The machine's own default service checklist wins."}},"additionalProperties":false,"description":"Update an existing group"}}}},"responses":{"200":{"description":"Group updated","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"orgId":{"type":"string","format":"uuid"},"name":{"type":"string"},"description":{"type":["string","null"]},"checklistTemplate":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"}},"required":["id","name"],"description":"Default checklist template for this group"},"serviceChecklistTemplate":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"}},"required":["id","name"],"description":"Default SERVICE checklist for a new service on a machine in this group. Null when none. Always sent."},"checkValidityMinutes":{"type":["integer","null"]},"checkValidityHours":{"type":["integer","null"],"description":"Deprecated: use checkValidityMinutes. The pre-start timer rounded down to whole hours, never below 1; removed in a future release."},"spotterRequired":{"type":["boolean","null"]},"operatorTimeoutMinutes":{"type":["integer","null"]},"serviceIntervalHours":{"type":["integer","null"]},"serviceIntervalDays":{"type":["integer","null"]},"serviceWarningHours":{"type":["integer","null"]},"serviceWarningDays":{"type":["integer","null"]},"preventStartWhenOverdue":{"type":["boolean","null"]},"unlockDurationSeconds":{"type":["integer","null"]},"alertOnIgnition":{"type":["boolean","null"]},"deviceCheckValidityMinutes":{"type":["integer","null"]},"deviceOperatorTimeoutMinutes":{"type":["integer","null"]},"bypassButtonEnabled":{"type":["boolean","null"]},"isActive":{"type":"boolean"},"code":{"type":["string","null"]},"requireDefectPhotos":{"type":["boolean","null"]},"equipmentCount":{"type":"integer"},"licenseCount":{"type":"integer"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"equipment":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"status":{"type":"string","enum":["ACTIVE","INACTIVE","MAINTENANCE","DECOMMISSIONED"]},"lockState":{"type":["string","null"],"enum":["UNREGISTERED","AWAITING_CONFIRM","LOCKED","UNLOCKED","OPERATOR_EXPIRED","SERVICE","BYPASS","ERROR",null]}},"required":["id","name","status","lockState"],"description":"Group equipment"}},"licenses":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"phone":{"type":"string"},"userId":{"type":["string","null"],"format":"uuid"},"userName":{"type":["string","null"]},"holder":{"type":["object","null"],"properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"A person: the name this org shows for them, where that name came from, and the contact that tells two same-named people apart"},"designation":{"type":["string","null"],"enum":["OPERATOR","SUPERVISOR","TECHNICIAN","LEAD",null]},"status":{"type":"string","enum":["PENDING","ACTIVE","REVOKED","EXPIRED","CANCELED"]},"isActive":{"type":"boolean"}},"required":["id","phone","userId","userName","holder","designation","status","isActive"],"description":"Group license"}}},"required":["id","orgId","name","description","checklistTemplate","checkValidityMinutes","checkValidityHours","spotterRequired","operatorTimeoutMinutes","serviceIntervalHours","serviceIntervalDays","serviceWarningHours","serviceWarningDays","preventStartWhenOverdue","unlockDurationSeconds","alertOnIgnition","deviceCheckValidityMinutes","deviceOperatorTimeoutMinutes","bypassButtonEnabled","isActive","code","requireDefectPhotos","equipmentCount","licenseCount","createdAt","updatedAt","equipment","licenses"],"description":"Group detail response"}},"required":["success","data"],"description":"Standard API success response"}}}}}},"delete":{"operationId":"deleteGroup","summary":"Delete group","description":"Soft-deletes a group. Equipment and users must be reassigned before deletion.","tags":["Groups"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"responses":{"204":{"description":"Group deleted"}}}},"/api/v1/devices":{"get":{"operationId":"listDevices","summary":"List devices","description":"Returns a paginated list of the Interlocks (`deviceType: SIM`) and Trackers (`deviceType: TM`) registered to the org.","tags":["Devices"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","maxLength":500},"required":false,"name":"after","in":"query"},{"schema":{"type":"string","maxLength":100},"required":false,"name":"search","in":"query"},{"schema":{"type":"string","enum":["SIM","TM"]},"required":false,"name":"type","in":"query"},{"schema":{"type":"string","format":"uuid"},"required":false,"name":"equipmentId","in":"query"},{"schema":{"type":"string","enum":["STARTER","SAFETY"]},"required":false,"name":"mode","in":"query"},{"schema":{"type":"boolean"},"required":false,"name":"isOnline","in":"query"}],"responses":{"200":{"description":"List of devices","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"serialNumber":{"type":"string"},"macAddress":{"type":["string","null"]},"type":{"type":"string","enum":["SIM","TM"]},"status":{"type":"string","enum":["ACTIVE","INACTIVE","UNREGISTERED"]},"isOnline":{"type":"boolean","description":"Whether the device is reporting: set by each reading it sends, and cleared when it has sent none for 30 minutes. An Interlock reports through the mobile app over Bluetooth and is normally false. Always sent."},"firmwareVersion":{"type":["string","null"]},"manufacturer":{"type":["string","null"]},"model":{"type":["string","null"]},"externalSerial":{"type":["string","null"]},"batteryLevel":{"type":["integer","null"]},"lastSeenAt":{"type":["string","null"],"format":"date-time"},"equipmentId":{"type":["string","null"],"format":"uuid"},"equipmentName":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":["string","null"],"format":"date-time"},"stateChangedAt":{"type":["string","null"],"format":"date-time"},"lockState":{"type":["object","null"],"properties":{"state":{"type":"string","enum":["UNREGISTERED","AWAITING_CONFIRM","LOCKED","UNLOCKED","OPERATOR_EXPIRED","SERVICE","BYPASS","ERROR"],"description":"The last recorded lock state"},"source":{"type":["string","null"],"enum":["COMMAND","ADV",null],"description":"Where it came from: COMMAND = read over an authenticated Bluetooth connection; ADV = decoded from the Interlock's Bluetooth advertising, which is not authenticated; null = written by a server-side change"},"observedAt":{"type":["string","null"],"format":"date-time","description":"When a phone observed it; null for a server-side change"}},"required":["state","source","observedAt"],"description":"The Interlock's last recorded lock state, the one stateChangedAt dates, with its provenance. Null for a Tracker, which never locks. Always sent."},"ignitionDetected":{"type":["boolean","null"]},"relayEnabled":{"type":["boolean","null"]},"totalRunSeconds":{"type":["integer","null"]},"sessionRunSeconds":{"type":["integer","null"]},"registeredByUserId":{"type":["string","null"],"format":"uuid"},"registeredVia":{"type":["string","null"]},"name":{"type":["string","null"],"minLength":1,"maxLength":255},"mode":{"type":"string","enum":["STARTER","SAFETY"]},"powerMode":{"type":"string","enum":["PERMANENT_POWER","IGNITION_POWER"]},"unlockDurationSeconds":{"type":["integer","null"],"minimum":60,"maximum":86400},"checkValidityMinutes":{"type":["integer","null"],"minimum":1},"operatorTimeoutMinutes":{"type":["integer","null"],"minimum":0},"alertOnIgnition":{"type":["boolean","null"]},"bypassButtonEnabled":{"type":["boolean","null"]},"timDetails":{"type":["object","null"],"properties":{"imei":{"type":["string","null"]},"iccid":{"type":["string","null"]},"signalStrength":{"type":["integer","null"]},"latitude":{"type":["number","null"],"minimum":-90,"maximum":90,"description":"WGS-84 latitude in decimal degrees (-90 to 90)"},"longitude":{"type":["number","null"],"minimum":-180,"maximum":180,"description":"WGS-84 longitude in decimal degrees (-180 to 180)"},"lastLocationAt":{"type":["string","null"],"format":"date-time"},"batteryVoltage":{"type":["number","null"]},"externalVoltage":{"type":["number","null"]},"isIgnitionOn":{"type":["boolean","null"]},"isMoving":{"type":["boolean","null"]},"lastSpeed":{"type":["number","null"]},"lastHeading":{"type":["number","null"]},"certificateExpiresAt":{"type":["string","null"],"format":"date-time"}},"required":["imei","iccid","signalStrength","latitude","longitude","lastLocationAt","batteryVoltage","externalVoltage","isIgnitionOn","isMoving","lastSpeed","lastHeading","certificateExpiresAt"],"description":"Tracker (`deviceType: TM`) cellular/GPS details"}},"required":["id","serialNumber","macAddress","type","status","firmwareVersion","manufacturer","model","externalSerial","batteryLevel","lastSeenAt","equipmentId","equipmentName","createdAt","updatedAt","stateChangedAt","ignitionDetected","relayEnabled","totalRunSeconds","sessionRunSeconds","registeredByUserId","registeredVia","name","mode","powerMode","unlockDurationSeconds","checkValidityMinutes","operatorTimeoutMinutes","alertOnIgnition","bypassButtonEnabled","timDetails"],"description":"Console device list/detail response (web console)"}},"meta":{"type":"object","properties":{"limit":{"type":"number"},"hasMore":{"type":"boolean"},"nextCursor":{"type":["string","null"]},"server_time":{"type":"integer"}},"required":["limit","hasMore","nextCursor"]}},"required":["success","data","meta"],"description":"Cursor-paginated API success response"}}}}}},"post":{"operationId":"registerDevice","summary":"Register a Tracker","description":"Registers a new Tracker (`deviceType: TM`) to the org using its serial number and MAC address (or claims a third-party Tracker by vendor serial). Interlock (`deviceType: SIM`) lifecycle is managed exclusively via the mobile app.","tags":["Devices"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"serialNumber":{"type":"string"},"externalSerial":{"type":"string","minLength":1,"maxLength":32},"macAddress":{"type":"string"},"type":{"type":"string","enum":["TM"]},"name":{"type":"string","minLength":1,"maxLength":255},"equipmentId":{"type":"string","format":"uuid"},"powerMode":{"type":"string","enum":["PERMANENT_POWER","IGNITION_POWER"]},"imei":{"type":"string"},"iccid":{"type":"string"}},"required":["type"],"additionalProperties":false,"description":"Register a new Tracker (`deviceType: TM`), or claim a third-party Tracker by vendor serial"}}}},"responses":{"201":{"description":"Device registered","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"serialNumber":{"type":"string"},"macAddress":{"type":["string","null"]},"type":{"type":"string","enum":["SIM","TM"]},"orgKey":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","serialNumber","macAddress","type","orgKey","createdAt"],"description":"Device registration response with org key"}},"required":["success","data"],"description":"Standard API success response"}}}},"409":{"description":"Duplicate serial number","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}}},"/api/v1/devices/below-ceiling":{"get":{"operationId":"listDevicesBelowCeiling","summary":"List Interlocks below the required limits","description":"Returns the Interlocks whose latest reported config holds a pre-start validity limit under 1440 minutes or an operator-timeout limit above 0 and under 180 minutes. A stored operator timeout of 0 means the operator confirms after every key-off, and counts as at its limit. The pre-start timers are sent with every unlock, and these stored limits cap them; a phone raises them on its next supervisor or technician connection. Devices no phone has reported are not listed. Values are the machine's own report, not the office record.","tags":["Devices"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","maxLength":500},"required":false,"name":"after","in":"query"}],"responses":{"200":{"description":"Interlocks reporting limits below the ceilings","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"serialNumber":{"type":"string"},"name":{"type":["string","null"]},"equipmentId":{"type":["string","null"],"format":"uuid"},"equipmentName":{"type":["string","null"]},"observedCheckValidityMinutes":{"type":"integer"},"observedOperatorTimeoutMinutes":{"type":"integer"},"configObservedAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","serialNumber","name","equipmentId","equipmentName","observedCheckValidityMinutes","observedOperatorTimeoutMinutes","configObservedAt","createdAt"],"description":"An Interlock whose latest reported limits are below the required ceilings"}},"meta":{"type":"object","properties":{"limit":{"type":"number"},"hasMore":{"type":"boolean"},"nextCursor":{"type":["string","null"]},"server_time":{"type":"integer"}},"required":["limit","hasMore","nextCursor"]}},"required":["success","data","meta"],"description":"Cursor-paginated API success response"}}}}}}},"/api/v1/devices/:id":{"get":{"operationId":"getDevice","summary":"Get device","description":"Returns full details of a device — an Interlock (`deviceType: SIM`) or a Tracker (`deviceType: TM`) — including firmware version, connectivity status, and linked equipment.","tags":["Devices"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Device details","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"serialNumber":{"type":"string"},"macAddress":{"type":["string","null"]},"type":{"type":"string","enum":["SIM","TM"]},"status":{"type":"string","enum":["ACTIVE","INACTIVE","UNREGISTERED"]},"isOnline":{"type":"boolean","description":"Whether the device is reporting: set by each reading it sends, and cleared when it has sent none for 30 minutes. An Interlock reports through the mobile app over Bluetooth and is normally false. Always sent."},"firmwareVersion":{"type":["string","null"]},"manufacturer":{"type":["string","null"]},"model":{"type":["string","null"]},"externalSerial":{"type":["string","null"]},"batteryLevel":{"type":["integer","null"]},"lastSeenAt":{"type":["string","null"],"format":"date-time"},"equipmentId":{"type":["string","null"],"format":"uuid"},"equipmentName":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":["string","null"],"format":"date-time"},"stateChangedAt":{"type":["string","null"],"format":"date-time"},"lockState":{"type":["object","null"],"properties":{"state":{"type":"string","enum":["UNREGISTERED","AWAITING_CONFIRM","LOCKED","UNLOCKED","OPERATOR_EXPIRED","SERVICE","BYPASS","ERROR"],"description":"The last recorded lock state"},"source":{"type":["string","null"],"enum":["COMMAND","ADV",null],"description":"Where it came from: COMMAND = read over an authenticated Bluetooth connection; ADV = decoded from the Interlock's Bluetooth advertising, which is not authenticated; null = written by a server-side change"},"observedAt":{"type":["string","null"],"format":"date-time","description":"When a phone observed it; null for a server-side change"}},"required":["state","source","observedAt"],"description":"The Interlock's last recorded lock state, the one stateChangedAt dates, with its provenance. Null for a Tracker, which never locks. Always sent."},"ignitionDetected":{"type":["boolean","null"]},"relayEnabled":{"type":["boolean","null"]},"totalRunSeconds":{"type":["integer","null"]},"sessionRunSeconds":{"type":["integer","null"]},"registeredByUserId":{"type":["string","null"],"format":"uuid"},"registeredVia":{"type":["string","null"]},"name":{"type":["string","null"],"minLength":1,"maxLength":255},"mode":{"type":"string","enum":["STARTER","SAFETY"]},"powerMode":{"type":"string","enum":["PERMANENT_POWER","IGNITION_POWER"]},"unlockDurationSeconds":{"type":["integer","null"],"minimum":60,"maximum":86400},"checkValidityMinutes":{"type":["integer","null"],"minimum":1},"operatorTimeoutMinutes":{"type":["integer","null"],"minimum":0},"alertOnIgnition":{"type":["boolean","null"]},"bypassButtonEnabled":{"type":["boolean","null"]},"timDetails":{"type":["object","null"],"properties":{"imei":{"type":["string","null"]},"iccid":{"type":["string","null"]},"signalStrength":{"type":["integer","null"]},"latitude":{"type":["number","null"],"minimum":-90,"maximum":90,"description":"WGS-84 latitude in decimal degrees (-90 to 90)"},"longitude":{"type":["number","null"],"minimum":-180,"maximum":180,"description":"WGS-84 longitude in decimal degrees (-180 to 180)"},"lastLocationAt":{"type":["string","null"],"format":"date-time"},"batteryVoltage":{"type":["number","null"]},"externalVoltage":{"type":["number","null"]},"isIgnitionOn":{"type":["boolean","null"]},"isMoving":{"type":["boolean","null"]},"lastSpeed":{"type":["number","null"]},"lastHeading":{"type":["number","null"]},"certificateExpiresAt":{"type":["string","null"],"format":"date-time"}},"required":["imei","iccid","signalStrength","latitude","longitude","lastLocationAt","batteryVoltage","externalVoltage","isIgnitionOn","isMoving","lastSpeed","lastHeading","certificateExpiresAt"],"description":"Tracker (`deviceType: TM`) cellular/GPS details"},"observedCheckValidityMinutes":{"type":["integer","null"]},"observedOperatorTimeoutMinutes":{"type":["integer","null"]},"observedBypassButtonEnabled":{"type":["boolean","null"]},"observedBypassTimeoutMinutes":{"type":["integer","null"]},"observedPowerMode":{"type":["string","null"],"enum":["PERMANENT_POWER","IGNITION_POWER",null]},"observedAuxiliaryMode":{"type":["string","null"],"enum":["OFF","SOLID","FLASH","BUZZER","FLASH_BUZZ",null]},"observedAccelRunningMg":{"type":["integer","null"]},"observedAccelLoadLowMg":{"type":["integer","null"]},"observedAccelLoadMedMg":{"type":["integer","null"]},"observedAccelLoadHighMg":{"type":["integer","null"]},"observedWroteAccelThresholds":{"type":["boolean","null"]},"observedWroteAuxiliaryMode":{"type":["boolean","null"]},"configObservedSource":{"type":["string","null"],"enum":["WRITE","READ",null]},"configObservedAt":{"type":["string","null"],"format":"date-time"}},"required":["id","serialNumber","macAddress","type","status","firmwareVersion","manufacturer","model","externalSerial","batteryLevel","lastSeenAt","equipmentId","equipmentName","createdAt","updatedAt","stateChangedAt","ignitionDetected","relayEnabled","totalRunSeconds","sessionRunSeconds","registeredByUserId","registeredVia","name","mode","powerMode","unlockDurationSeconds","checkValidityMinutes","operatorTimeoutMinutes","alertOnIgnition","bypassButtonEnabled","timDetails","observedCheckValidityMinutes","observedOperatorTimeoutMinutes","observedBypassButtonEnabled","observedBypassTimeoutMinutes","observedPowerMode","observedAuxiliaryMode","observedAccelRunningMg","observedAccelLoadLowMg","observedAccelLoadMedMg","observedAccelLoadHighMg","observedWroteAccelThresholds","observedWroteAuxiliaryMode","configObservedSource","configObservedAt"],"description":"Console device DETAIL response — the list shape plus the machine-reported config"}},"required":["success","data"],"description":"Standard API success response"}}}},"404":{"description":"Device not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}},"patch":{"operationId":"updateDevice","summary":"Update device","description":"Updates device properties (an Interlock (`deviceType: SIM`) or a Tracker (`deviceType: TM`)) such as name or configuration settings.","tags":["Devices"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":255},"mode":{"type":"string","enum":["STARTER","SAFETY"]}},"additionalProperties":false,"description":"Update a device — an Interlock (`deviceType: SIM`) or a Tracker (`deviceType: TM`)"}}}},"responses":{"200":{"description":"Device updated","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"serialNumber":{"type":"string"},"macAddress":{"type":["string","null"]},"type":{"type":"string","enum":["SIM","TM"]},"status":{"type":"string","enum":["ACTIVE","INACTIVE","UNREGISTERED"]},"isOnline":{"type":"boolean","description":"Whether the device is reporting: set by each reading it sends, and cleared when it has sent none for 30 minutes. An Interlock reports through the mobile app over Bluetooth and is normally false. Always sent."},"firmwareVersion":{"type":["string","null"]},"manufacturer":{"type":["string","null"]},"model":{"type":["string","null"]},"externalSerial":{"type":["string","null"]},"batteryLevel":{"type":["integer","null"]},"lastSeenAt":{"type":["string","null"],"format":"date-time"},"equipmentId":{"type":["string","null"],"format":"uuid"},"equipmentName":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":["string","null"],"format":"date-time"},"stateChangedAt":{"type":["string","null"],"format":"date-time"},"lockState":{"type":["object","null"],"properties":{"state":{"type":"string","enum":["UNREGISTERED","AWAITING_CONFIRM","LOCKED","UNLOCKED","OPERATOR_EXPIRED","SERVICE","BYPASS","ERROR"],"description":"The last recorded lock state"},"source":{"type":["string","null"],"enum":["COMMAND","ADV",null],"description":"Where it came from: COMMAND = read over an authenticated Bluetooth connection; ADV = decoded from the Interlock's Bluetooth advertising, which is not authenticated; null = written by a server-side change"},"observedAt":{"type":["string","null"],"format":"date-time","description":"When a phone observed it; null for a server-side change"}},"required":["state","source","observedAt"],"description":"The Interlock's last recorded lock state, the one stateChangedAt dates, with its provenance. Null for a Tracker, which never locks. Always sent."},"ignitionDetected":{"type":["boolean","null"]},"relayEnabled":{"type":["boolean","null"]},"totalRunSeconds":{"type":["integer","null"]},"sessionRunSeconds":{"type":["integer","null"]},"registeredByUserId":{"type":["string","null"],"format":"uuid"},"registeredVia":{"type":["string","null"]},"name":{"type":["string","null"],"minLength":1,"maxLength":255},"mode":{"type":"string","enum":["STARTER","SAFETY"]},"powerMode":{"type":"string","enum":["PERMANENT_POWER","IGNITION_POWER"]},"unlockDurationSeconds":{"type":["integer","null"],"minimum":60,"maximum":86400},"checkValidityMinutes":{"type":["integer","null"],"minimum":1},"operatorTimeoutMinutes":{"type":["integer","null"],"minimum":0},"alertOnIgnition":{"type":["boolean","null"]},"bypassButtonEnabled":{"type":["boolean","null"]},"timDetails":{"type":["object","null"],"properties":{"imei":{"type":["string","null"]},"iccid":{"type":["string","null"]},"signalStrength":{"type":["integer","null"]},"latitude":{"type":["number","null"],"minimum":-90,"maximum":90,"description":"WGS-84 latitude in decimal degrees (-90 to 90)"},"longitude":{"type":["number","null"],"minimum":-180,"maximum":180,"description":"WGS-84 longitude in decimal degrees (-180 to 180)"},"lastLocationAt":{"type":["string","null"],"format":"date-time"},"batteryVoltage":{"type":["number","null"]},"externalVoltage":{"type":["number","null"]},"isIgnitionOn":{"type":["boolean","null"]},"isMoving":{"type":["boolean","null"]},"lastSpeed":{"type":["number","null"]},"lastHeading":{"type":["number","null"]},"certificateExpiresAt":{"type":["string","null"],"format":"date-time"}},"required":["imei","iccid","signalStrength","latitude","longitude","lastLocationAt","batteryVoltage","externalVoltage","isIgnitionOn","isMoving","lastSpeed","lastHeading","certificateExpiresAt"],"description":"Tracker (`deviceType: TM`) cellular/GPS details"},"observedCheckValidityMinutes":{"type":["integer","null"]},"observedOperatorTimeoutMinutes":{"type":["integer","null"]},"observedBypassButtonEnabled":{"type":["boolean","null"]},"observedBypassTimeoutMinutes":{"type":["integer","null"]},"observedPowerMode":{"type":["string","null"],"enum":["PERMANENT_POWER","IGNITION_POWER",null]},"observedAuxiliaryMode":{"type":["string","null"],"enum":["OFF","SOLID","FLASH","BUZZER","FLASH_BUZZ",null]},"observedAccelRunningMg":{"type":["integer","null"]},"observedAccelLoadLowMg":{"type":["integer","null"]},"observedAccelLoadMedMg":{"type":["integer","null"]},"observedAccelLoadHighMg":{"type":["integer","null"]},"observedWroteAccelThresholds":{"type":["boolean","null"]},"observedWroteAuxiliaryMode":{"type":["boolean","null"]},"configObservedSource":{"type":["string","null"],"enum":["WRITE","READ",null]},"configObservedAt":{"type":["string","null"],"format":"date-time"}},"required":["id","serialNumber","macAddress","type","status","firmwareVersion","manufacturer","model","externalSerial","batteryLevel","lastSeenAt","equipmentId","equipmentName","createdAt","updatedAt","stateChangedAt","ignitionDetected","relayEnabled","totalRunSeconds","sessionRunSeconds","registeredByUserId","registeredVia","name","mode","powerMode","unlockDurationSeconds","checkValidityMinutes","operatorTimeoutMinutes","alertOnIgnition","bypassButtonEnabled","timDetails","observedCheckValidityMinutes","observedOperatorTimeoutMinutes","observedBypassButtonEnabled","observedBypassTimeoutMinutes","observedPowerMode","observedAuxiliaryMode","observedAccelRunningMg","observedAccelLoadLowMg","observedAccelLoadMedMg","observedAccelLoadHighMg","observedWroteAccelThresholds","observedWroteAuxiliaryMode","configObservedSource","configObservedAt"],"description":"Console device DETAIL response — the list shape plus the machine-reported config"}},"required":["success","data"],"description":"Standard API success response"}}}}}},"delete":{"operationId":"deleteDevice","summary":"Delete device","description":"Soft-deletes a device. An Interlock (`deviceType: SIM`) is decommissioned via the mobile app instead. A Tracker still linked to equipment is unlinked in the same step. Requires OWNER, matching device registration.","tags":["Devices"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"responses":{"204":{"description":"Device deleted"},"404":{"description":"Device not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}}},"/api/v1/devices/:id/link":{"patch":{"operationId":"linkDevice","summary":"Link or unlink a device to equipment","description":"Links a device to equipment's interlock slot, or unlinks it by passing null. An Interlock (`deviceType: SIM`) is linked via the mobile app; a Tracker (`deviceType: TM`) binds via /:id/bind.","tags":["Devices"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"equipmentId":{"type":["string","null"],"format":"uuid"}},"required":["equipmentId"],"additionalProperties":false,"description":"Link or unlink a device to equipment"}}}},"responses":{"200":{"description":"Updated device with link status","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"serialNumber":{"type":"string"},"macAddress":{"type":["string","null"]},"type":{"type":"string","enum":["SIM","TM"]},"status":{"type":"string","enum":["ACTIVE","INACTIVE","UNREGISTERED"]},"isOnline":{"type":"boolean","description":"Whether the device is reporting: set by each reading it sends, and cleared when it has sent none for 30 minutes. An Interlock reports through the mobile app over Bluetooth and is normally false. Always sent."},"firmwareVersion":{"type":["string","null"]},"manufacturer":{"type":["string","null"]},"model":{"type":["string","null"]},"externalSerial":{"type":["string","null"]},"batteryLevel":{"type":["integer","null"]},"lastSeenAt":{"type":["string","null"],"format":"date-time"},"equipmentId":{"type":["string","null"],"format":"uuid"},"equipmentName":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":["string","null"],"format":"date-time"},"stateChangedAt":{"type":["string","null"],"format":"date-time"},"lockState":{"type":["object","null"],"properties":{"state":{"type":"string","enum":["UNREGISTERED","AWAITING_CONFIRM","LOCKED","UNLOCKED","OPERATOR_EXPIRED","SERVICE","BYPASS","ERROR"],"description":"The last recorded lock state"},"source":{"type":["string","null"],"enum":["COMMAND","ADV",null],"description":"Where it came from: COMMAND = read over an authenticated Bluetooth connection; ADV = decoded from the Interlock's Bluetooth advertising, which is not authenticated; null = written by a server-side change"},"observedAt":{"type":["string","null"],"format":"date-time","description":"When a phone observed it; null for a server-side change"}},"required":["state","source","observedAt"],"description":"The Interlock's last recorded lock state, the one stateChangedAt dates, with its provenance. Null for a Tracker, which never locks. Always sent."},"ignitionDetected":{"type":["boolean","null"]},"relayEnabled":{"type":["boolean","null"]},"totalRunSeconds":{"type":["integer","null"]},"sessionRunSeconds":{"type":["integer","null"]},"registeredByUserId":{"type":["string","null"],"format":"uuid"},"registeredVia":{"type":["string","null"]},"name":{"type":["string","null"],"minLength":1,"maxLength":255},"mode":{"type":"string","enum":["STARTER","SAFETY"]},"powerMode":{"type":"string","enum":["PERMANENT_POWER","IGNITION_POWER"]},"unlockDurationSeconds":{"type":["integer","null"],"minimum":60,"maximum":86400},"checkValidityMinutes":{"type":["integer","null"],"minimum":1},"operatorTimeoutMinutes":{"type":["integer","null"],"minimum":0},"alertOnIgnition":{"type":["boolean","null"]},"bypassButtonEnabled":{"type":["boolean","null"]},"timDetails":{"type":["object","null"],"properties":{"imei":{"type":["string","null"]},"iccid":{"type":["string","null"]},"signalStrength":{"type":["integer","null"]},"latitude":{"type":["number","null"],"minimum":-90,"maximum":90,"description":"WGS-84 latitude in decimal degrees (-90 to 90)"},"longitude":{"type":["number","null"],"minimum":-180,"maximum":180,"description":"WGS-84 longitude in decimal degrees (-180 to 180)"},"lastLocationAt":{"type":["string","null"],"format":"date-time"},"batteryVoltage":{"type":["number","null"]},"externalVoltage":{"type":["number","null"]},"isIgnitionOn":{"type":["boolean","null"]},"isMoving":{"type":["boolean","null"]},"lastSpeed":{"type":["number","null"]},"lastHeading":{"type":["number","null"]},"certificateExpiresAt":{"type":["string","null"],"format":"date-time"}},"required":["imei","iccid","signalStrength","latitude","longitude","lastLocationAt","batteryVoltage","externalVoltage","isIgnitionOn","isMoving","lastSpeed","lastHeading","certificateExpiresAt"],"description":"Tracker (`deviceType: TM`) cellular/GPS details"},"observedCheckValidityMinutes":{"type":["integer","null"]},"observedOperatorTimeoutMinutes":{"type":["integer","null"]},"observedBypassButtonEnabled":{"type":["boolean","null"]},"observedBypassTimeoutMinutes":{"type":["integer","null"]},"observedPowerMode":{"type":["string","null"],"enum":["PERMANENT_POWER","IGNITION_POWER",null]},"observedAuxiliaryMode":{"type":["string","null"],"enum":["OFF","SOLID","FLASH","BUZZER","FLASH_BUZZ",null]},"observedAccelRunningMg":{"type":["integer","null"]},"observedAccelLoadLowMg":{"type":["integer","null"]},"observedAccelLoadMedMg":{"type":["integer","null"]},"observedAccelLoadHighMg":{"type":["integer","null"]},"observedWroteAccelThresholds":{"type":["boolean","null"]},"observedWroteAuxiliaryMode":{"type":["boolean","null"]},"configObservedSource":{"type":["string","null"],"enum":["WRITE","READ",null]},"configObservedAt":{"type":["string","null"],"format":"date-time"}},"required":["id","serialNumber","macAddress","type","status","firmwareVersion","manufacturer","model","externalSerial","batteryLevel","lastSeenAt","equipmentId","equipmentName","createdAt","updatedAt","stateChangedAt","ignitionDetected","relayEnabled","totalRunSeconds","sessionRunSeconds","registeredByUserId","registeredVia","name","mode","powerMode","unlockDurationSeconds","checkValidityMinutes","operatorTimeoutMinutes","alertOnIgnition","bypassButtonEnabled","timDetails","observedCheckValidityMinutes","observedOperatorTimeoutMinutes","observedBypassButtonEnabled","observedBypassTimeoutMinutes","observedPowerMode","observedAuxiliaryMode","observedAccelRunningMg","observedAccelLoadLowMg","observedAccelLoadMedMg","observedAccelLoadHighMg","observedWroteAccelThresholds","observedWroteAuxiliaryMode","configObservedSource","configObservedAt"],"description":"Console device DETAIL response — the list shape plus the machine-reported config"}},"required":["success","data"],"description":"Standard API success response"}}}},"404":{"description":"Device or equipment not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}}},"/api/v1/devices/:id/bind":{"patch":{"operationId":"bindTelemetryDevice","summary":"Bind or unbind a Tracker to equipment","description":"Binds a standalone Tracker (`deviceType: TM`) to a machine's telemetry slot, or unbinds it by passing null. Use /:id/link for an Interlock (`deviceType: SIM`).","tags":["Devices"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"equipmentId":{"type":["string","null"],"format":"uuid"}},"required":["equipmentId"],"additionalProperties":false,"description":"Link or unlink a device to equipment"}}}},"responses":{"200":{"description":"Updated device with telemetry binding","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"serialNumber":{"type":"string"},"macAddress":{"type":["string","null"]},"type":{"type":"string","enum":["SIM","TM"]},"status":{"type":"string","enum":["ACTIVE","INACTIVE","UNREGISTERED"]},"isOnline":{"type":"boolean","description":"Whether the device is reporting: set by each reading it sends, and cleared when it has sent none for 30 minutes. An Interlock reports through the mobile app over Bluetooth and is normally false. Always sent."},"firmwareVersion":{"type":["string","null"]},"manufacturer":{"type":["string","null"]},"model":{"type":["string","null"]},"externalSerial":{"type":["string","null"]},"batteryLevel":{"type":["integer","null"]},"lastSeenAt":{"type":["string","null"],"format":"date-time"},"equipmentId":{"type":["string","null"],"format":"uuid"},"equipmentName":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":["string","null"],"format":"date-time"},"stateChangedAt":{"type":["string","null"],"format":"date-time"},"lockState":{"type":["object","null"],"properties":{"state":{"type":"string","enum":["UNREGISTERED","AWAITING_CONFIRM","LOCKED","UNLOCKED","OPERATOR_EXPIRED","SERVICE","BYPASS","ERROR"],"description":"The last recorded lock state"},"source":{"type":["string","null"],"enum":["COMMAND","ADV",null],"description":"Where it came from: COMMAND = read over an authenticated Bluetooth connection; ADV = decoded from the Interlock's Bluetooth advertising, which is not authenticated; null = written by a server-side change"},"observedAt":{"type":["string","null"],"format":"date-time","description":"When a phone observed it; null for a server-side change"}},"required":["state","source","observedAt"],"description":"The Interlock's last recorded lock state, the one stateChangedAt dates, with its provenance. Null for a Tracker, which never locks. Always sent."},"ignitionDetected":{"type":["boolean","null"]},"relayEnabled":{"type":["boolean","null"]},"totalRunSeconds":{"type":["integer","null"]},"sessionRunSeconds":{"type":["integer","null"]},"registeredByUserId":{"type":["string","null"],"format":"uuid"},"registeredVia":{"type":["string","null"]},"name":{"type":["string","null"],"minLength":1,"maxLength":255},"mode":{"type":"string","enum":["STARTER","SAFETY"]},"powerMode":{"type":"string","enum":["PERMANENT_POWER","IGNITION_POWER"]},"unlockDurationSeconds":{"type":["integer","null"],"minimum":60,"maximum":86400},"checkValidityMinutes":{"type":["integer","null"],"minimum":1},"operatorTimeoutMinutes":{"type":["integer","null"],"minimum":0},"alertOnIgnition":{"type":["boolean","null"]},"bypassButtonEnabled":{"type":["boolean","null"]},"timDetails":{"type":["object","null"],"properties":{"imei":{"type":["string","null"]},"iccid":{"type":["string","null"]},"signalStrength":{"type":["integer","null"]},"latitude":{"type":["number","null"],"minimum":-90,"maximum":90,"description":"WGS-84 latitude in decimal degrees (-90 to 90)"},"longitude":{"type":["number","null"],"minimum":-180,"maximum":180,"description":"WGS-84 longitude in decimal degrees (-180 to 180)"},"lastLocationAt":{"type":["string","null"],"format":"date-time"},"batteryVoltage":{"type":["number","null"]},"externalVoltage":{"type":["number","null"]},"isIgnitionOn":{"type":["boolean","null"]},"isMoving":{"type":["boolean","null"]},"lastSpeed":{"type":["number","null"]},"lastHeading":{"type":["number","null"]},"certificateExpiresAt":{"type":["string","null"],"format":"date-time"}},"required":["imei","iccid","signalStrength","latitude","longitude","lastLocationAt","batteryVoltage","externalVoltage","isIgnitionOn","isMoving","lastSpeed","lastHeading","certificateExpiresAt"],"description":"Tracker (`deviceType: TM`) cellular/GPS details"},"observedCheckValidityMinutes":{"type":["integer","null"]},"observedOperatorTimeoutMinutes":{"type":["integer","null"]},"observedBypassButtonEnabled":{"type":["boolean","null"]},"observedBypassTimeoutMinutes":{"type":["integer","null"]},"observedPowerMode":{"type":["string","null"],"enum":["PERMANENT_POWER","IGNITION_POWER",null]},"observedAuxiliaryMode":{"type":["string","null"],"enum":["OFF","SOLID","FLASH","BUZZER","FLASH_BUZZ",null]},"observedAccelRunningMg":{"type":["integer","null"]},"observedAccelLoadLowMg":{"type":["integer","null"]},"observedAccelLoadMedMg":{"type":["integer","null"]},"observedAccelLoadHighMg":{"type":["integer","null"]},"observedWroteAccelThresholds":{"type":["boolean","null"]},"observedWroteAuxiliaryMode":{"type":["boolean","null"]},"configObservedSource":{"type":["string","null"],"enum":["WRITE","READ",null]},"configObservedAt":{"type":["string","null"],"format":"date-time"}},"required":["id","serialNumber","macAddress","type","status","firmwareVersion","manufacturer","model","externalSerial","batteryLevel","lastSeenAt","equipmentId","equipmentName","createdAt","updatedAt","stateChangedAt","ignitionDetected","relayEnabled","totalRunSeconds","sessionRunSeconds","registeredByUserId","registeredVia","name","mode","powerMode","unlockDurationSeconds","checkValidityMinutes","operatorTimeoutMinutes","alertOnIgnition","bypassButtonEnabled","timDetails","observedCheckValidityMinutes","observedOperatorTimeoutMinutes","observedBypassButtonEnabled","observedBypassTimeoutMinutes","observedPowerMode","observedAuxiliaryMode","observedAccelRunningMg","observedAccelLoadLowMg","observedAccelLoadMedMg","observedAccelLoadHighMg","observedWroteAccelThresholds","observedWroteAuxiliaryMode","configObservedSource","configObservedAt"],"description":"Console device DETAIL response — the list shape plus the machine-reported config"}},"required":["success","data"],"description":"Standard API success response"}}}},"400":{"description":"Device is not a Tracker (`deviceType: TM`) or has no telemetry record","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}},"404":{"description":"Device or equipment not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}}},"/api/v1/devices/:id/service-logs":{"get":{"operationId":"listDeviceServiceLogs","summary":"Get service mode logs","description":"Returns a paginated list of service mode enable/disable events for the specified Interlock (`deviceType: SIM`).","tags":["Devices"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","maxLength":500},"required":false,"name":"after","in":"query"}],"responses":{"200":{"description":"Service mode logs","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"deviceId":{"type":"string","format":"uuid"},"equipmentId":{"type":["string","null"],"format":"uuid"},"orgId":{"type":"string","format":"uuid"},"action":{"type":"string","enum":["ENABLE","DISABLE"]},"reason":{"type":["string","null"],"maxLength":500},"userId":{"type":"string","format":"uuid"},"userName":{"type":"string","minLength":1,"maxLength":255},"user":{"type":["object","null"],"properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"A person: the name this org shows for them, where that name came from, and the contact that tells two same-named people apart"},"userRole":{"type":"string","minLength":1,"maxLength":50},"latitude":{"type":["number","null"],"minimum":-90,"maximum":90,"description":"WGS-84 latitude in decimal degrees (-90 to 90)"},"longitude":{"type":["number","null"],"minimum":-180,"maximum":180,"description":"WGS-84 longitude in decimal degrees (-180 to 180)"},"createdAt":{"type":["string","null"],"format":"date-time"}},"required":["id","deviceId","orgId","action","userId","userName","user","userRole","createdAt"],"description":"Service mode activation/deactivation log (append-only)"}},"meta":{"type":"object","properties":{"limit":{"type":"number"},"hasMore":{"type":"boolean"},"nextCursor":{"type":["string","null"]},"server_time":{"type":"integer"}},"required":["limit","hasMore","nextCursor"]}},"required":["success","data","meta"],"description":"Cursor-paginated API success response"}}}}}}},"/api/v1/devices/:id/rotate-key":{"post":{"operationId":"rotateDeviceKey","summary":"Initiate org key rotation","description":"Mints a new PENDING org key for the Interlock (`deviceType: SIM`) and stops. It does not contact the device: delivery is phone-mediated and asynchronous — the next SUPERVISOR or TECHNICIAN phone to connect fetches the pending key, relays it to the Interlock in a SET_ORG_KEY packet signed with the current key, and reports the outcome, which is what promotes it. The Interlock keeps working on its existing key throughout; nothing changes until that acknowledgment lands. An undelivered pending key expires after 24 hours and is discarded rather than left promotable.","tags":["Devices"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"responses":{"200":{"description":"Key rotation initiated","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"pendingOrgKey":{"type":"string","description":"Show-once: the pending org key. Treat as a secret — it will not be shown again."},"pendingOrgKeyCreatedAt":{"type":"string","format":"date-time"}},"required":["id","pendingOrgKey","pendingOrgKeyCreatedAt"],"description":"Org key rotation response with pending key"}},"required":["success","data"],"description":"Standard API success response"}}}},"404":{"description":"Device not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}}},"/api/v1/devices/:id/confirm-key-rotation":{"post":{"operationId":"confirmDeviceKeyRotation","summary":"Confirm org key rotation","description":"Reports whether an org key rotation has been acknowledged by the device — it does NOT promote one. Promotion happens only when a phone relays the new key over BLE and the Interlock accepts it; a console caller cannot know that happened, so asserting it here is no longer possible. Returns 200 when the most recent rotation was promoted by a device acknowledgment, 409 `rotation.not_acknowledged` while one is still awaiting delivery, and 400 `device.no_pending_rotation` when there is nothing pending and no completed rotation to report. The one mutation this endpoint still performs is housekeeping: a pending key past its 24-hour deadline is discarded (with an audit record) and returns 400 `device.pending_rotation_expired`.","tags":["Devices"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"responses":{"200":{"description":"Rotation was already promoted by a device acknowledgment","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"confirmed":{"type":"boolean","enum":[true]}},"required":["id","confirmed"],"description":"Org key rotation confirmation response"}},"required":["success","data"],"description":"Standard API success response"}}}},"400":{"description":"No pending rotation and none recently completed (`device.no_pending_rotation`), or the pending key passed its 24-hour deadline and was discarded (`device.pending_rotation_expired`)","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}},"404":{"description":"Device not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}},"409":{"description":"Pending rotation has not been acknowledged by the device","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}}},"/api/v1/checklists":{"get":{"operationId":"listChecklists","summary":"List templates","description":"Returns a paginated list of checklist templates for the authenticated org. Templates define the check questions used in pre-start checks.","tags":["Checklists"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","maxLength":500},"required":false,"name":"after","in":"query"},{"schema":{"type":"string","enum":["PRESTART","SERVICE","EQUIPMENT_INDUCTION","TOOLBOX"]},"required":false,"name":"type","in":"query"},{"schema":{"type":"string","maxLength":100},"required":false,"name":"search","in":"query"},{"schema":{"type":"boolean"},"required":false,"name":"isActive","in":"query"}],"responses":{"200":{"description":"List of templates","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"description":{"type":["string","null"]},"type":{"type":"string","enum":["PRESTART","SERVICE","EQUIPMENT_INDUCTION","TOOLBOX"]},"version":{"type":"integer"},"isActive":{"type":"boolean"},"sectionCount":{"type":"integer"},"itemCount":{"type":"integer"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","name","description","type","version","isActive","sectionCount","itemCount","createdAt"],"description":"Checklist template list item response"}},"meta":{"type":"object","properties":{"limit":{"type":"number"},"hasMore":{"type":"boolean"},"nextCursor":{"type":["string","null"]},"server_time":{"type":"integer"}},"required":["limit","hasMore","nextCursor"]}},"required":["success","data","meta"],"description":"Cursor-paginated API success response"}}}}}},"post":{"operationId":"createChecklist","summary":"Create template","description":"Creates a new checklist template with sections and questions. Templates are assigned to equipment types for pre-start checks.","tags":["Checklists"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":255},"description":{"type":"string","maxLength":1000},"type":{"type":"string","enum":["PRESTART","SERVICE","EQUIPMENT_INDUCTION","TOOLBOX"],"default":"PRESTART"},"sections":{"type":"array","items":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":255},"description":{"type":["string","null"],"maxLength":2000},"order":{"type":"integer","minimum":0,"maximum":100},"items":{"type":"array","items":{"type":"object","properties":{"text":{"type":"string","minLength":1,"maxLength":500},"type":{"type":"string","enum":["PASS_FAIL","TEXT","NUMBER","SELECT","MULTI_SELECT","DATE","TIME","PHOTO","SIGNATURE","INSTRUCTION"]},"order":{"type":"integer","minimum":0,"maximum":1000},"isRequired":{"type":"boolean","default":true},"isCritical":{"type":"boolean","default":false},"description":{"type":["string","null"],"maxLength":2000},"options":{"type":["array","null"],"items":{"type":"string","maxLength":255},"maxItems":50},"failOn":{"type":["array","null"],"items":{"type":"string","maxLength":255},"maxItems":50},"min":{"type":["number","null"]},"max":{"type":["number","null"]}},"required":["text","type","order"]},"minItems":1,"maxItems":200}},"required":["title","order","items"]},"minItems":1,"maxItems":50},"ungroupedItems":{"type":"array","items":{"type":"object","properties":{"text":{"type":"string","minLength":1,"maxLength":500},"type":{"type":"string","enum":["PASS_FAIL","TEXT","NUMBER","SELECT","MULTI_SELECT","DATE","TIME","PHOTO","SIGNATURE","INSTRUCTION"]},"order":{"type":"integer","minimum":0,"maximum":1000},"isRequired":{"type":"boolean","default":true},"isCritical":{"type":"boolean","default":false},"description":{"type":["string","null"],"maxLength":2000},"options":{"type":["array","null"],"items":{"type":"string","maxLength":255},"maxItems":50},"failOn":{"type":["array","null"],"items":{"type":"string","maxLength":255},"maxItems":50},"min":{"type":["number","null"]},"max":{"type":["number","null"]}},"required":["text","type","order"]},"maxItems":200}},"required":["name","sections"],"additionalProperties":false,"description":"Create a new checklist template with sections and items"}}}},"responses":{"201":{"description":"Template created","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"orgId":{"type":"string","format":"uuid"},"name":{"type":"string","minLength":1,"maxLength":255},"description":{"type":["string","null"],"maxLength":2000},"type":{"type":"string","enum":["PRESTART","SERVICE","EQUIPMENT_INDUCTION","TOOLBOX"]},"version":{"type":"integer","minimum":1,"maximum":9999,"default":1},"isActive":{"type":"boolean"},"isPublic":{"type":"boolean"},"createdAt":{"type":["string","null"],"format":"date-time"},"updatedAt":{"type":["string","null"],"format":"date-time"},"deletedAt":{"type":["string","null"],"format":"date-time"},"createdByUserId":{"type":["string","null"],"format":"uuid"},"updatedByUserId":{"type":["string","null"],"format":"uuid"},"deletedByUserId":{"type":["string","null"],"format":"uuid"},"sections":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"orgId":{"type":"string","format":"uuid"},"templateId":{"type":"string","format":"uuid"},"title":{"type":"string","minLength":1,"maxLength":255},"description":{"type":["string","null"],"maxLength":2000},"order":{"type":"integer","minimum":0,"maximum":100,"default":0},"createdAt":{"type":["string","null"],"format":"date-time"},"updatedAt":{"type":["string","null"],"format":"date-time"},"deletedAt":{"type":["string","null"],"format":"date-time"},"createdByUserId":{"type":["string","null"],"format":"uuid"},"updatedByUserId":{"type":["string","null"],"format":"uuid"},"deletedByUserId":{"type":["string","null"],"format":"uuid"},"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"orgId":{"type":"string","format":"uuid"},"templateId":{"type":"string","format":"uuid"},"sectionId":{"type":["string","null"],"format":"uuid"},"text":{"type":"string","minLength":1,"maxLength":500},"description":{"type":["string","null"],"maxLength":2000},"type":{"type":"string","enum":["PASS_FAIL","TEXT","NUMBER","SELECT","MULTI_SELECT","DATE","TIME","PHOTO","SIGNATURE","INSTRUCTION"]},"isRequired":{"type":"boolean"},"order":{"type":"integer","minimum":0,"maximum":1000},"options":{"type":["array","null"],"items":{"type":"string","maxLength":255},"maxItems":50},"failOn":{"type":["array","null"],"items":{"type":"string","maxLength":255},"maxItems":50},"isCritical":{"type":"boolean"},"min":{"type":["number","null"]},"max":{"type":["number","null"]},"createdAt":{"type":["string","null"],"format":"date-time"},"updatedAt":{"type":["string","null"],"format":"date-time"},"deletedAt":{"type":["string","null"],"format":"date-time"},"createdByUserId":{"type":["string","null"],"format":"uuid"},"updatedByUserId":{"type":["string","null"],"format":"uuid"},"deletedByUserId":{"type":["string","null"],"format":"uuid"}},"required":["id","orgId","templateId","text","type","isRequired","order","isCritical","createdAt","updatedAt"]}}},"required":["id","orgId","templateId","title","createdAt","updatedAt","items"]},"maxItems":50},"ungroupedItems":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"orgId":{"type":"string","format":"uuid"},"templateId":{"type":"string","format":"uuid"},"sectionId":{"type":["string","null"],"format":"uuid"},"text":{"type":"string","minLength":1,"maxLength":500},"description":{"type":["string","null"],"maxLength":2000},"type":{"type":"string","enum":["PASS_FAIL","TEXT","NUMBER","SELECT","MULTI_SELECT","DATE","TIME","PHOTO","SIGNATURE","INSTRUCTION"]},"isRequired":{"type":"boolean"},"order":{"type":"integer","minimum":0,"maximum":1000},"options":{"type":["array","null"],"items":{"type":"string","maxLength":255},"maxItems":50},"failOn":{"type":["array","null"],"items":{"type":"string","maxLength":255},"maxItems":50},"isCritical":{"type":"boolean"},"min":{"type":["number","null"]},"max":{"type":["number","null"]},"createdAt":{"type":["string","null"],"format":"date-time"},"updatedAt":{"type":["string","null"],"format":"date-time"},"deletedAt":{"type":["string","null"],"format":"date-time"},"createdByUserId":{"type":["string","null"],"format":"uuid"},"updatedByUserId":{"type":["string","null"],"format":"uuid"},"deletedByUserId":{"type":["string","null"],"format":"uuid"}},"required":["id","orgId","templateId","text","type","isRequired","order","isCritical","createdAt","updatedAt"]},"maxItems":200},"usage":{"type":"object","properties":{"groupCount":{"type":"integer","minimum":0,"description":"Groups using it as their pre-start default"},"equipmentCount":{"type":"integer","minimum":0,"description":"Machines using it as their own pre-start default"},"serviceGroupCount":{"type":"integer","minimum":0,"description":"Groups using it as their default service checklist"},"serviceEquipmentCount":{"type":"integer","minimum":0,"description":"Machines using it as their own default service checklist"}},"required":["groupCount","equipmentCount","serviceGroupCount","serviceEquipmentCount"],"description":"Where a checklist template is used as a default"}},"required":["id","orgId","name","type","isActive","isPublic","createdAt","updatedAt","sections","ungroupedItems"],"description":"Complete checklist template with sections and items"}},"required":["success","data"],"description":"Standard API success response"}}}}}}},"/api/v1/checklists/:id":{"get":{"operationId":"getChecklist","summary":"Get template","description":"Returns full details of a checklist template, including all sections and questions.","tags":["Checklists"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Template details","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"orgId":{"type":"string","format":"uuid"},"name":{"type":"string","minLength":1,"maxLength":255},"description":{"type":["string","null"],"maxLength":2000},"type":{"type":"string","enum":["PRESTART","SERVICE","EQUIPMENT_INDUCTION","TOOLBOX"]},"version":{"type":"integer","minimum":1,"maximum":9999,"default":1},"isActive":{"type":"boolean"},"isPublic":{"type":"boolean"},"createdAt":{"type":["string","null"],"format":"date-time"},"updatedAt":{"type":["string","null"],"format":"date-time"},"deletedAt":{"type":["string","null"],"format":"date-time"},"createdByUserId":{"type":["string","null"],"format":"uuid"},"updatedByUserId":{"type":["string","null"],"format":"uuid"},"deletedByUserId":{"type":["string","null"],"format":"uuid"},"sections":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"orgId":{"type":"string","format":"uuid"},"templateId":{"type":"string","format":"uuid"},"title":{"type":"string","minLength":1,"maxLength":255},"description":{"type":["string","null"],"maxLength":2000},"order":{"type":"integer","minimum":0,"maximum":100,"default":0},"createdAt":{"type":["string","null"],"format":"date-time"},"updatedAt":{"type":["string","null"],"format":"date-time"},"deletedAt":{"type":["string","null"],"format":"date-time"},"createdByUserId":{"type":["string","null"],"format":"uuid"},"updatedByUserId":{"type":["string","null"],"format":"uuid"},"deletedByUserId":{"type":["string","null"],"format":"uuid"},"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"orgId":{"type":"string","format":"uuid"},"templateId":{"type":"string","format":"uuid"},"sectionId":{"type":["string","null"],"format":"uuid"},"text":{"type":"string","minLength":1,"maxLength":500},"description":{"type":["string","null"],"maxLength":2000},"type":{"type":"string","enum":["PASS_FAIL","TEXT","NUMBER","SELECT","MULTI_SELECT","DATE","TIME","PHOTO","SIGNATURE","INSTRUCTION"]},"isRequired":{"type":"boolean"},"order":{"type":"integer","minimum":0,"maximum":1000},"options":{"type":["array","null"],"items":{"type":"string","maxLength":255},"maxItems":50},"failOn":{"type":["array","null"],"items":{"type":"string","maxLength":255},"maxItems":50},"isCritical":{"type":"boolean"},"min":{"type":["number","null"]},"max":{"type":["number","null"]},"createdAt":{"type":["string","null"],"format":"date-time"},"updatedAt":{"type":["string","null"],"format":"date-time"},"deletedAt":{"type":["string","null"],"format":"date-time"},"createdByUserId":{"type":["string","null"],"format":"uuid"},"updatedByUserId":{"type":["string","null"],"format":"uuid"},"deletedByUserId":{"type":["string","null"],"format":"uuid"}},"required":["id","orgId","templateId","text","type","isRequired","order","isCritical","createdAt","updatedAt"]}}},"required":["id","orgId","templateId","title","createdAt","updatedAt","items"]},"maxItems":50},"ungroupedItems":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"orgId":{"type":"string","format":"uuid"},"templateId":{"type":"string","format":"uuid"},"sectionId":{"type":["string","null"],"format":"uuid"},"text":{"type":"string","minLength":1,"maxLength":500},"description":{"type":["string","null"],"maxLength":2000},"type":{"type":"string","enum":["PASS_FAIL","TEXT","NUMBER","SELECT","MULTI_SELECT","DATE","TIME","PHOTO","SIGNATURE","INSTRUCTION"]},"isRequired":{"type":"boolean"},"order":{"type":"integer","minimum":0,"maximum":1000},"options":{"type":["array","null"],"items":{"type":"string","maxLength":255},"maxItems":50},"failOn":{"type":["array","null"],"items":{"type":"string","maxLength":255},"maxItems":50},"isCritical":{"type":"boolean"},"min":{"type":["number","null"]},"max":{"type":["number","null"]},"createdAt":{"type":["string","null"],"format":"date-time"},"updatedAt":{"type":["string","null"],"format":"date-time"},"deletedAt":{"type":["string","null"],"format":"date-time"},"createdByUserId":{"type":["string","null"],"format":"uuid"},"updatedByUserId":{"type":["string","null"],"format":"uuid"},"deletedByUserId":{"type":["string","null"],"format":"uuid"}},"required":["id","orgId","templateId","text","type","isRequired","order","isCritical","createdAt","updatedAt"]},"maxItems":200},"usage":{"type":"object","properties":{"groupCount":{"type":"integer","minimum":0,"description":"Groups using it as their pre-start default"},"equipmentCount":{"type":"integer","minimum":0,"description":"Machines using it as their own pre-start default"},"serviceGroupCount":{"type":"integer","minimum":0,"description":"Groups using it as their default service checklist"},"serviceEquipmentCount":{"type":"integer","minimum":0,"description":"Machines using it as their own default service checklist"}},"required":["groupCount","equipmentCount","serviceGroupCount","serviceEquipmentCount"],"description":"Where a checklist template is used as a default"}},"required":["id","orgId","name","type","isActive","isPublic","createdAt","updatedAt","sections","ungroupedItems"],"description":"Complete checklist template with sections and items"}},"required":["success","data"],"description":"Standard API success response"}}}},"404":{"description":"Template not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}},"patch":{"operationId":"updateChecklist","summary":"Update template","description":"Updates an existing checklist template, including its sections and questions.","tags":["Checklists"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":255},"description":{"type":["string","null"],"maxLength":1000},"type":{"type":"string","enum":["PRESTART","SERVICE","EQUIPMENT_INDUCTION","TOOLBOX"]},"isActive":{"type":"boolean"},"sections":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"title":{"type":"string","minLength":1,"maxLength":255},"description":{"type":["string","null"],"maxLength":2000},"order":{"type":"integer","minimum":0,"maximum":100},"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"text":{"type":"string","minLength":1,"maxLength":500},"type":{"type":"string","enum":["PASS_FAIL","TEXT","NUMBER","SELECT","MULTI_SELECT","DATE","TIME","PHOTO","SIGNATURE","INSTRUCTION"]},"order":{"type":"integer","minimum":0,"maximum":1000},"isRequired":{"type":"boolean","default":true},"isCritical":{"type":"boolean","default":false},"description":{"type":["string","null"],"maxLength":2000},"options":{"type":["array","null"],"items":{"type":"string","maxLength":255},"maxItems":50},"failOn":{"type":["array","null"],"items":{"type":"string","maxLength":255},"maxItems":50},"min":{"type":["number","null"]},"max":{"type":["number","null"]}},"required":["text","type","order"]},"minItems":1,"maxItems":200}},"required":["title","order","items"]},"maxItems":50},"ungroupedItems":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"text":{"type":"string","minLength":1,"maxLength":500},"type":{"type":"string","enum":["PASS_FAIL","TEXT","NUMBER","SELECT","MULTI_SELECT","DATE","TIME","PHOTO","SIGNATURE","INSTRUCTION"]},"order":{"type":"integer","minimum":0,"maximum":1000},"isRequired":{"type":"boolean","default":true},"isCritical":{"type":"boolean","default":false},"description":{"type":["string","null"],"maxLength":2000},"options":{"type":["array","null"],"items":{"type":"string","maxLength":255},"maxItems":50},"failOn":{"type":["array","null"],"items":{"type":"string","maxLength":255},"maxItems":50},"min":{"type":["number","null"]},"max":{"type":["number","null"]}},"required":["text","type","order"]},"maxItems":200}},"additionalProperties":false,"description":"Update a checklist template"}}}},"responses":{"200":{"description":"Template updated","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"orgId":{"type":"string","format":"uuid"},"name":{"type":"string","minLength":1,"maxLength":255},"description":{"type":["string","null"],"maxLength":2000},"type":{"type":"string","enum":["PRESTART","SERVICE","EQUIPMENT_INDUCTION","TOOLBOX"]},"version":{"type":"integer","minimum":1,"maximum":9999,"default":1},"isActive":{"type":"boolean"},"isPublic":{"type":"boolean"},"createdAt":{"type":["string","null"],"format":"date-time"},"updatedAt":{"type":["string","null"],"format":"date-time"},"deletedAt":{"type":["string","null"],"format":"date-time"},"createdByUserId":{"type":["string","null"],"format":"uuid"},"updatedByUserId":{"type":["string","null"],"format":"uuid"},"deletedByUserId":{"type":["string","null"],"format":"uuid"},"sections":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"orgId":{"type":"string","format":"uuid"},"templateId":{"type":"string","format":"uuid"},"title":{"type":"string","minLength":1,"maxLength":255},"description":{"type":["string","null"],"maxLength":2000},"order":{"type":"integer","minimum":0,"maximum":100,"default":0},"createdAt":{"type":["string","null"],"format":"date-time"},"updatedAt":{"type":["string","null"],"format":"date-time"},"deletedAt":{"type":["string","null"],"format":"date-time"},"createdByUserId":{"type":["string","null"],"format":"uuid"},"updatedByUserId":{"type":["string","null"],"format":"uuid"},"deletedByUserId":{"type":["string","null"],"format":"uuid"},"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"orgId":{"type":"string","format":"uuid"},"templateId":{"type":"string","format":"uuid"},"sectionId":{"type":["string","null"],"format":"uuid"},"text":{"type":"string","minLength":1,"maxLength":500},"description":{"type":["string","null"],"maxLength":2000},"type":{"type":"string","enum":["PASS_FAIL","TEXT","NUMBER","SELECT","MULTI_SELECT","DATE","TIME","PHOTO","SIGNATURE","INSTRUCTION"]},"isRequired":{"type":"boolean"},"order":{"type":"integer","minimum":0,"maximum":1000},"options":{"type":["array","null"],"items":{"type":"string","maxLength":255},"maxItems":50},"failOn":{"type":["array","null"],"items":{"type":"string","maxLength":255},"maxItems":50},"isCritical":{"type":"boolean"},"min":{"type":["number","null"]},"max":{"type":["number","null"]},"createdAt":{"type":["string","null"],"format":"date-time"},"updatedAt":{"type":["string","null"],"format":"date-time"},"deletedAt":{"type":["string","null"],"format":"date-time"},"createdByUserId":{"type":["string","null"],"format":"uuid"},"updatedByUserId":{"type":["string","null"],"format":"uuid"},"deletedByUserId":{"type":["string","null"],"format":"uuid"}},"required":["id","orgId","templateId","text","type","isRequired","order","isCritical","createdAt","updatedAt"]}}},"required":["id","orgId","templateId","title","createdAt","updatedAt","items"]},"maxItems":50},"ungroupedItems":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"orgId":{"type":"string","format":"uuid"},"templateId":{"type":"string","format":"uuid"},"sectionId":{"type":["string","null"],"format":"uuid"},"text":{"type":"string","minLength":1,"maxLength":500},"description":{"type":["string","null"],"maxLength":2000},"type":{"type":"string","enum":["PASS_FAIL","TEXT","NUMBER","SELECT","MULTI_SELECT","DATE","TIME","PHOTO","SIGNATURE","INSTRUCTION"]},"isRequired":{"type":"boolean"},"order":{"type":"integer","minimum":0,"maximum":1000},"options":{"type":["array","null"],"items":{"type":"string","maxLength":255},"maxItems":50},"failOn":{"type":["array","null"],"items":{"type":"string","maxLength":255},"maxItems":50},"isCritical":{"type":"boolean"},"min":{"type":["number","null"]},"max":{"type":["number","null"]},"createdAt":{"type":["string","null"],"format":"date-time"},"updatedAt":{"type":["string","null"],"format":"date-time"},"deletedAt":{"type":["string","null"],"format":"date-time"},"createdByUserId":{"type":["string","null"],"format":"uuid"},"updatedByUserId":{"type":["string","null"],"format":"uuid"},"deletedByUserId":{"type":["string","null"],"format":"uuid"}},"required":["id","orgId","templateId","text","type","isRequired","order","isCritical","createdAt","updatedAt"]},"maxItems":200},"usage":{"type":"object","properties":{"groupCount":{"type":"integer","minimum":0,"description":"Groups using it as their pre-start default"},"equipmentCount":{"type":"integer","minimum":0,"description":"Machines using it as their own pre-start default"},"serviceGroupCount":{"type":"integer","minimum":0,"description":"Groups using it as their default service checklist"},"serviceEquipmentCount":{"type":"integer","minimum":0,"description":"Machines using it as their own default service checklist"}},"required":["groupCount","equipmentCount","serviceGroupCount","serviceEquipmentCount"],"description":"Where a checklist template is used as a default"}},"required":["id","orgId","name","type","isActive","isPublic","createdAt","updatedAt","sections","ungroupedItems"],"description":"Complete checklist template with sections and items"}},"required":["success","data"],"description":"Standard API success response"}}}},"404":{"description":"Template not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}},"409":{"description":"Deactivation refused: the template is the pre-start default of a group or equipment (`checklist_template.in_use`; `details` carries `groupCount` and `equipmentCount`)","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}},"delete":{"operationId":"deleteChecklist","summary":"Delete template","description":"Soft-deletes a checklist template. Existing checks that used this template are not affected. Refused while the template is the pre-start default of a group or equipment.","tags":["Checklists"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"responses":{"204":{"description":"Template deleted"},"409":{"description":"The template is the pre-start default of a group or equipment (`checklist_template.in_use`; `details` carries `groupCount` and `equipmentCount`)","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}}},"/api/v1/reports/email-opt-outs":{"delete":{"operationId":"removeReportEmailOptOut","summary":"Restore a recipient who had opted out of report emails","description":"Removes this org's opt-out for one address so scheduled reports may be delivered to it again. MANAGER+ and audited: re-subscribing someone who asked to be left alone is a consent decision. 404 if no opt-out exists for the address in this org.","tags":["Reports"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"email"},"required":true,"name":"email","in":"query"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"responses":{"204":{"description":"Opt-out removed"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}},"404":{"description":"No opt-out found for that address","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}}},"/api/v1/reports":{"get":{"operationId":"listReports","summary":"List reports","description":"Returns a paginated list of previously generated reports for the authenticated org.","tags":["Reports"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","maxLength":500},"required":false,"name":"after","in":"query"},{"schema":{"type":"string","enum":["EQUIPMENT_PRESTART","SITE_COMPLIANCE","SITE_EMISSIONS","EQUIPMENT_HISTORY","DEFECT_SUMMARY","SERVICE_DUE","BYPASS_EVENTS","SPOT_CHECK_SUMMARY","SPEED_VIOLATIONS","UTILIZATION_SUMMARY","SERVICE_HISTORY"]},"required":false,"name":"type","in":"query"},{"schema":{"type":"string","enum":["PENDING","GENERATING","COMPLETED","EMAILED","FAILED"]},"required":false,"name":"status","in":"query"},{"schema":{"type":"boolean","description":"When `true`, list only reports requested by the authenticated user. An API key has no requesting user, so `mine=true` with an API key returns an empty page."},"required":false,"description":"When `true`, list only reports requested by the authenticated user. An API key has no requesting user, so `mine=true` with an API key returns an empty page.","name":"mine","in":"query"}],"responses":{"200":{"description":"Reports","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"type":{"type":"string","enum":["EQUIPMENT_PRESTART","SITE_COMPLIANCE","SITE_EMISSIONS","EQUIPMENT_HISTORY","DEFECT_SUMMARY","SERVICE_DUE","BYPASS_EVENTS","SPOT_CHECK_SUMMARY","SPEED_VIOLATIONS","UTILIZATION_SUMMARY","SERVICE_HISTORY"]},"status":{"type":"string","enum":["PENDING","GENERATING","COMPLETED","EMAILED","FAILED"]},"format":{"type":"string","enum":["CSV","XLSX","PDF"]},"siteId":{"type":["string","null"],"format":"uuid"},"periodStart":{"type":["string","null"],"format":"date-time"},"periodEnd":{"type":["string","null"],"format":"date-time"},"filters":{"type":["object","null"],"additionalProperties":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}},"fileUrl":{"type":["string","null"],"maxLength":2048,"format":"uri"},"fileSize":{"type":["integer","null"],"minimum":0},"emailTo":{"type":["array","null"],"items":{"type":"string","format":"email"}},"failureCode":{"type":["string","null"],"enum":["RENDER","STORAGE","DELIVERY","ENQUEUE","UNKNOWN",null]},"createdAt":{"type":"string","format":"date-time"},"completedAt":{"type":["string","null"],"format":"date-time"}},"required":["id","type","status","format","siteId","periodStart","periodEnd","filters","fileUrl","fileSize","emailTo","failureCode","createdAt","completedAt"],"description":"Generated report response"}},"meta":{"type":"object","properties":{"limit":{"type":"number"},"hasMore":{"type":"boolean"},"nextCursor":{"type":["string","null"]},"server_time":{"type":"integer"}},"required":["limit","hasMore","nextCursor"]}},"required":["success","data","meta"],"description":"Cursor-paginated API success response"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}}},"/api/v1/reports/generate":{"post":{"operationId":"generateReport","summary":"Request report","description":"Queues generation of a new report for the specified type and date range. The report is generated asynchronously.","tags":["Reports"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string","enum":["EQUIPMENT_PRESTART","SITE_COMPLIANCE","SITE_EMISSIONS","EQUIPMENT_HISTORY","DEFECT_SUMMARY","SERVICE_DUE","BYPASS_EVENTS","SPOT_CHECK_SUMMARY","SPEED_VIOLATIONS","UTILIZATION_SUMMARY","SERVICE_HISTORY"]},"siteId":{"type":"string","format":"uuid"},"format":{"type":"string","enum":["CSV","XLSX","PDF"],"default":"CSV"},"periodFrom":{"type":"string","format":"date-time"},"periodTo":{"type":"string","format":"date-time"},"filters":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}},"emailTo":{"type":"array","items":{"type":"string"},"minItems":1,"maxItems":50}},"required":["type"],"additionalProperties":false,"description":"Generate a report for a specified period"}}}},"responses":{"202":{"description":"Report requested","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"type":{"type":"string","enum":["EQUIPMENT_PRESTART","SITE_COMPLIANCE","SITE_EMISSIONS","EQUIPMENT_HISTORY","DEFECT_SUMMARY","SERVICE_DUE","BYPASS_EVENTS","SPOT_CHECK_SUMMARY","SPEED_VIOLATIONS","UTILIZATION_SUMMARY","SERVICE_HISTORY"]},"status":{"type":"string","enum":["PENDING","GENERATING","COMPLETED","EMAILED","FAILED"]},"format":{"type":"string","enum":["CSV","XLSX","PDF"]},"siteId":{"type":["string","null"],"format":"uuid"},"periodStart":{"type":["string","null"],"format":"date-time"},"periodEnd":{"type":["string","null"],"format":"date-time"},"filters":{"type":["object","null"],"additionalProperties":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}},"fileUrl":{"type":["string","null"],"maxLength":2048,"format":"uri"},"fileSize":{"type":["integer","null"],"minimum":0},"emailTo":{"type":["array","null"],"items":{"type":"string","format":"email"}},"failureCode":{"type":["string","null"],"enum":["RENDER","STORAGE","DELIVERY","ENQUEUE","UNKNOWN",null]},"createdAt":{"type":"string","format":"date-time"},"completedAt":{"type":["string","null"],"format":"date-time"}},"required":["id","type","status","format","siteId","periodStart","periodEnd","filters","fileUrl","fileSize","emailTo","failureCode","createdAt","completedAt"],"description":"Generated report response"}},"required":["success","data"],"description":"Standard API success response"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}}},"/api/v1/reports/preview":{"get":{"operationId":"previewReport","summary":"Preview a report","description":"Computes a capped-row preview of a report without generating/storing a file. Not cursor-paginated — a computed aggregate, capped at 500 rows.","tags":["Reports"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","enum":["EQUIPMENT_PRESTART","SITE_COMPLIANCE","SITE_EMISSIONS","EQUIPMENT_HISTORY","DEFECT_SUMMARY","SERVICE_DUE","BYPASS_EVENTS","SPOT_CHECK_SUMMARY","SPEED_VIOLATIONS","UTILIZATION_SUMMARY","SERVICE_HISTORY"]},"required":true,"name":"type","in":"query"},{"schema":{"type":"string","format":"uuid"},"required":false,"name":"siteId","in":"query"},{"schema":{"type":"string","format":"date-time"},"required":false,"name":"periodFrom","in":"query"},{"schema":{"type":"string","format":"date-time"},"required":false,"name":"periodTo","in":"query"},{"schema":{"type":"string"},"required":false,"name":"filters","in":"query"}],"responses":{"200":{"description":"Report preview","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"type":{"type":"string","enum":["EQUIPMENT_PRESTART","SITE_COMPLIANCE","SITE_EMISSIONS","EQUIPMENT_HISTORY","DEFECT_SUMMARY","SERVICE_DUE","BYPASS_EVENTS","SPOT_CHECK_SUMMARY","SPEED_VIOLATIONS","UTILIZATION_SUMMARY","SERVICE_HISTORY"]},"title":{"type":"string"},"columns":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string"},"header":{"type":"string"},"width":{"type":"number"},"align":{"type":"string","enum":["left","right","center"]},"kind":{"type":"string","enum":["string","number","date","boolean"]}},"required":["key","header"]}},"rows":{"type":"array","items":{"type":"object","additionalProperties":{}}},"meta":{"type":"object","properties":{"orgId":{"type":"string","format":"uuid"},"siteId":{"type":["string","null"],"format":"uuid"},"siteName":{"type":["string","null"]},"periodStart":{"type":["string","null"],"format":"date-time"},"periodEnd":{"type":["string","null"],"format":"date-time"},"filters":{"type":["object","null"],"additionalProperties":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}},"generatedAt":{"type":"string","format":"date-time"},"rowCount":{"type":"integer","minimum":0},"truncated":{"type":"boolean"},"suggestedPeriod":{"type":"object","properties":{"from":{"type":"string","format":"date-time"},"to":{"type":"string","format":"date-time"},"timeZone":{"type":"string"},"reason":{"type":"string","enum":["NO_ROWS","NO_ACTIVITY"]}},"required":["from","to","timeZone","reason"],"description":"A nearby reporting period that contains data"}},"required":["orgId","siteId","siteName","periodStart","periodEnd","filters","generatedAt","rowCount"]}},"required":["type","title","columns","rows","meta"],"description":"Report preview response"}},"required":["success","data"],"description":"Standard API success response"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}}},"/api/v1/reports/:id/download-url":{"get":{"operationId":"getReportDownloadUrl","summary":"Get a fresh report download URL","description":"Mints a fresh, short-lived (15 minute) signed download URL for a previously generated report. Unlike the URLs embedded in GET / (which are signed once per page load and go stale once the console stops polling a terminal report), this can be called again any time — e.g. from a Download button — to get a URL that is guaranteed not to have expired yet. 404 for a report belonging to another org or past the 90-day retention window.","tags":["Reports"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Signed download URL","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"url":{"type":"string","maxLength":2048,"format":"uri"},"expiresAt":{"type":"string","format":"date-time"},"filename":{"type":"string","minLength":1,"maxLength":255}},"required":["url","expiresAt","filename"],"description":"Short-lived signed download URL for a generated report"}},"required":["success","data"],"description":"Standard API success response"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}},"404":{"description":"Report not found, belongs to another org, or past its retention window","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}}},"/api/v1/reports/subscriptions":{"get":{"operationId":"listReportSubscriptions","summary":"List report subscriptions","description":"Returns a paginated list of report subscriptions for the authenticated org.","tags":["Reports"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","maxLength":500},"required":false,"name":"after","in":"query"}],"responses":{"200":{"description":"Subscriptions","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"type":{"type":"string","enum":["EQUIPMENT_PRESTART","SITE_COMPLIANCE","SITE_EMISSIONS","EQUIPMENT_HISTORY","DEFECT_SUMMARY","SERVICE_DUE","BYPASS_EVENTS","SPOT_CHECK_SUMMARY","SPEED_VIOLATIONS","UTILIZATION_SUMMARY","SERVICE_HISTORY"]},"siteId":{"type":["string","null"],"format":"uuid"},"frequency":{"type":"string","enum":["DAILY","WEEKLY","MONTHLY","QUARTERLY","YEARLY","ON_DEMAND"]},"format":{"type":"string","enum":["CSV","XLSX","PDF"]},"dayOfWeek":{"type":["integer","null"],"minimum":0,"maximum":6},"dayOfMonth":{"type":["integer","null"],"minimum":1,"maximum":31},"timeOfDay":{"type":["string","null"]},"timezone":{"type":["string","null"]},"filters":{"type":["object","null"],"additionalProperties":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}},"recipients":{"type":"array","items":{"type":"string","format":"email"},"maxItems":100},"optedOutRecipients":{"type":"array","items":{"type":"string","format":"email"}},"isActive":{"type":"boolean"},"lastGeneratedAt":{"type":["string","null"],"format":"date-time"},"nextRunAt":{"type":["string","null"],"format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"consecutiveFailures":{"type":"integer","minimum":0},"lastRunStatus":{"type":["string","null"],"enum":["PENDING","GENERATING","COMPLETED","EMAILED","FAILED",null]},"triggerEvent":{"type":["string","null"],"enum":["CRITICAL_DEFECT_OPENED",null]}},"required":["id","name","type","siteId","frequency","format","dayOfWeek","dayOfMonth","timeOfDay","timezone","filters","recipients","optedOutRecipients","isActive","lastGeneratedAt","nextRunAt","createdAt","consecutiveFailures","lastRunStatus","triggerEvent"],"description":"Report subscription list item response"}},"meta":{"type":"object","properties":{"limit":{"type":"number"},"hasMore":{"type":"boolean"},"nextCursor":{"type":["string","null"]},"server_time":{"type":"integer"}},"required":["limit","hasMore","nextCursor"]}},"required":["success","data","meta"],"description":"Cursor-paginated API success response"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}},"post":{"operationId":"createReportSubscription","summary":"Create report subscription","description":"Creates a new scheduled report subscription.","tags":["Reports"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"reportType":{"type":"string","enum":["EQUIPMENT_PRESTART","SITE_COMPLIANCE","SITE_EMISSIONS","EQUIPMENT_HISTORY","DEFECT_SUMMARY","SERVICE_DUE","BYPASS_EVENTS","SPOT_CHECK_SUMMARY","SPEED_VIOLATIONS","UTILIZATION_SUMMARY","SERVICE_HISTORY"]},"name":{"type":"string","minLength":1,"maxLength":255},"siteId":{"type":"string","format":"uuid"},"frequency":{"type":"string","enum":["DAILY","WEEKLY","MONTHLY","QUARTERLY","YEARLY","ON_DEMAND"]},"format":{"type":"string","enum":["CSV","XLSX","PDF"],"default":"CSV"},"dayOfWeek":{"type":"integer","minimum":0,"maximum":6},"dayOfMonth":{"type":"integer","minimum":1,"maximum":31},"timeOfDay":{"type":"string"},"timezone":{"type":"string","minLength":1,"maxLength":50},"filters":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}},"recipients":{"type":"array","items":{"type":"string"},"minItems":1,"maxItems":50},"triggerEvent":{"type":"string","enum":["CRITICAL_DEFECT_OPENED"]}},"required":["reportType","name","frequency","recipients"],"additionalProperties":false,"description":"Create a scheduled report subscription"}}}},"responses":{"201":{"description":"Subscription created","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"type":{"type":"string","enum":["EQUIPMENT_PRESTART","SITE_COMPLIANCE","SITE_EMISSIONS","EQUIPMENT_HISTORY","DEFECT_SUMMARY","SERVICE_DUE","BYPASS_EVENTS","SPOT_CHECK_SUMMARY","SPEED_VIOLATIONS","UTILIZATION_SUMMARY","SERVICE_HISTORY"]},"siteId":{"type":["string","null"],"format":"uuid"},"frequency":{"type":"string","enum":["DAILY","WEEKLY","MONTHLY","QUARTERLY","YEARLY","ON_DEMAND"]},"format":{"type":"string","enum":["CSV","XLSX","PDF"]},"dayOfWeek":{"type":["integer","null"],"minimum":0,"maximum":6},"dayOfMonth":{"type":["integer","null"],"minimum":1,"maximum":31},"timeOfDay":{"type":["string","null"]},"timezone":{"type":["string","null"]},"filters":{"type":["object","null"],"additionalProperties":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}},"recipients":{"type":"array","items":{"type":"string","format":"email"},"maxItems":100},"optedOutRecipients":{"type":"array","items":{"type":"string","format":"email"}},"isActive":{"type":"boolean"},"lastGeneratedAt":{"type":["string","null"],"format":"date-time"},"nextRunAt":{"type":["string","null"],"format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"consecutiveFailures":{"type":"integer","minimum":0},"lastRunStatus":{"type":["string","null"],"enum":["PENDING","GENERATING","COMPLETED","EMAILED","FAILED",null]},"triggerEvent":{"type":["string","null"],"enum":["CRITICAL_DEFECT_OPENED",null]}},"required":["id","name","type","siteId","frequency","format","dayOfWeek","dayOfMonth","timeOfDay","timezone","filters","recipients","optedOutRecipients","isActive","lastGeneratedAt","nextRunAt","createdAt","consecutiveFailures","lastRunStatus","triggerEvent"],"description":"Report subscription list item response"}},"required":["success","data"],"description":"Standard API success response"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}}},"/api/v1/reports/subscriptions/:id":{"patch":{"operationId":"updateReportSubscription","summary":"Update report subscription","description":"Updates an existing report subscription.","tags":["Reports"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":255},"reportType":{"type":"string","enum":["EQUIPMENT_PRESTART","SITE_COMPLIANCE","SITE_EMISSIONS","EQUIPMENT_HISTORY","DEFECT_SUMMARY","SERVICE_DUE","BYPASS_EVENTS","SPOT_CHECK_SUMMARY","SPEED_VIOLATIONS","UTILIZATION_SUMMARY","SERVICE_HISTORY"]},"siteId":{"type":["string","null"],"format":"uuid"},"frequency":{"type":"string","enum":["DAILY","WEEKLY","MONTHLY","QUARTERLY","YEARLY","ON_DEMAND"]},"format":{"type":"string","enum":["CSV","XLSX","PDF"]},"dayOfWeek":{"type":"integer","minimum":0,"maximum":6},"dayOfMonth":{"type":"integer","minimum":1,"maximum":31},"timeOfDay":{"type":"string"},"timezone":{"type":"string","minLength":1,"maxLength":50},"filters":{"type":["object","null"],"additionalProperties":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}},"recipients":{"type":"array","items":{"type":"string"},"minItems":1,"maxItems":50},"isActive":{"type":"boolean"},"triggerEvent":{"type":["string","null"],"enum":["CRITICAL_DEFECT_OPENED",null]}},"additionalProperties":false,"description":"Update a scheduled report subscription"}}}},"responses":{"200":{"description":"Subscription updated","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"type":{"type":"string","enum":["EQUIPMENT_PRESTART","SITE_COMPLIANCE","SITE_EMISSIONS","EQUIPMENT_HISTORY","DEFECT_SUMMARY","SERVICE_DUE","BYPASS_EVENTS","SPOT_CHECK_SUMMARY","SPEED_VIOLATIONS","UTILIZATION_SUMMARY","SERVICE_HISTORY"]},"siteId":{"type":["string","null"],"format":"uuid"},"frequency":{"type":"string","enum":["DAILY","WEEKLY","MONTHLY","QUARTERLY","YEARLY","ON_DEMAND"]},"format":{"type":"string","enum":["CSV","XLSX","PDF"]},"dayOfWeek":{"type":["integer","null"],"minimum":0,"maximum":6},"dayOfMonth":{"type":["integer","null"],"minimum":1,"maximum":31},"timeOfDay":{"type":["string","null"]},"timezone":{"type":["string","null"]},"filters":{"type":["object","null"],"additionalProperties":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}},"recipients":{"type":"array","items":{"type":"string","format":"email"},"maxItems":100},"optedOutRecipients":{"type":"array","items":{"type":"string","format":"email"}},"isActive":{"type":"boolean"},"lastGeneratedAt":{"type":["string","null"],"format":"date-time"},"nextRunAt":{"type":["string","null"],"format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"consecutiveFailures":{"type":"integer","minimum":0},"lastRunStatus":{"type":["string","null"],"enum":["PENDING","GENERATING","COMPLETED","EMAILED","FAILED",null]},"triggerEvent":{"type":["string","null"],"enum":["CRITICAL_DEFECT_OPENED",null]}},"required":["id","name","type","siteId","frequency","format","dayOfWeek","dayOfMonth","timeOfDay","timezone","filters","recipients","optedOutRecipients","isActive","lastGeneratedAt","nextRunAt","createdAt","consecutiveFailures","lastRunStatus","triggerEvent"],"description":"Report subscription list item response"}},"required":["success","data"],"description":"Standard API success response"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}},"404":{"description":"Subscription not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}},"delete":{"operationId":"deleteReportSubscription","summary":"Delete report subscription","description":"Soft-deletes a report subscription.","tags":["Reports"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"responses":{"204":{"description":"Subscription deleted"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}},"404":{"description":"Subscription not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}}},"/api/v1/reports/subscriptions/:id/send":{"post":{"operationId":"sendReportSubscriptionNow","summary":"Send report subscription now","description":"Immediately enqueues generation of this subscription's report using its current config, without touching nextRunAt.","tags":["Reports"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"responses":{"202":{"description":"Report generation queued","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"type":{"type":"string","enum":["EQUIPMENT_PRESTART","SITE_COMPLIANCE","SITE_EMISSIONS","EQUIPMENT_HISTORY","DEFECT_SUMMARY","SERVICE_DUE","BYPASS_EVENTS","SPOT_CHECK_SUMMARY","SPEED_VIOLATIONS","UTILIZATION_SUMMARY","SERVICE_HISTORY"]},"status":{"type":"string","enum":["PENDING","GENERATING","COMPLETED","EMAILED","FAILED"]},"format":{"type":"string","enum":["CSV","XLSX","PDF"]},"siteId":{"type":["string","null"],"format":"uuid"},"periodStart":{"type":["string","null"],"format":"date-time"},"periodEnd":{"type":["string","null"],"format":"date-time"},"filters":{"type":["object","null"],"additionalProperties":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}},"fileUrl":{"type":["string","null"],"maxLength":2048,"format":"uri"},"fileSize":{"type":["integer","null"],"minimum":0},"emailTo":{"type":["array","null"],"items":{"type":"string","format":"email"}},"failureCode":{"type":["string","null"],"enum":["RENDER","STORAGE","DELIVERY","ENQUEUE","UNKNOWN",null]},"createdAt":{"type":"string","format":"date-time"},"completedAt":{"type":["string","null"],"format":"date-time"}},"required":["id","type","status","format","siteId","periodStart","periodEnd","filters","fileUrl","fileSize","emailTo","failureCode","createdAt","completedAt"],"description":"Generated report response"}},"required":["success","data"],"description":"Standard API success response"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}},"404":{"description":"Subscription not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}}},"/api/v1/alerts":{"get":{"operationId":"listAlerts","summary":"List alerts","description":"Returns a paginated list of alerts for the authenticated org. Alerts are triggered by compliance events such as failed checks or overdue checks.","tags":["Alerts"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","maxLength":500},"required":false,"name":"after","in":"query"},{"schema":{"type":"string","maxLength":100},"required":false,"name":"search","in":"query"},{"schema":{"type":"string","enum":["ACTIVE","ACKNOWLEDGED","RESOLVED","DISMISSED","OPEN"],"description":"One alert status, or OPEN for any open status (ACTIVE or ACKNOWLEDGED)"},"required":false,"description":"One alert status, or OPEN for any open status (ACTIVE or ACKNOWLEDGED)","name":"status","in":"query"},{"schema":{"type":"string","enum":["LOW","MEDIUM","HIGH","CRITICAL"]},"required":false,"name":"severity","in":"query"},{"schema":{"type":"string","format":"uuid"},"required":false,"name":"siteId","in":"query"},{"schema":{"type":"string","format":"uuid"},"required":false,"name":"equipmentId","in":"query"}],"responses":{"200":{"description":"List of alerts","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"title":{"type":"string"},"description":{"type":"string"},"status":{"type":"string","enum":["ACTIVE","ACKNOWLEDGED","RESOLVED","DISMISSED"]},"severity":{"type":"string","enum":["LOW","MEDIUM","HIGH","CRITICAL"]},"metadata":{"type":["object","null"],"additionalProperties":{}},"equipment":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"}},"required":["id","name"],"description":"Related equipment"},"user":{"type":["object","null"],"properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"Person who triggered the alert"},"acknowledgedAt":{"type":["string","null"],"format":"date-time"},"acknowledgedByUserId":{"type":["string","null"],"format":"uuid"},"resolvedAt":{"type":["string","null"],"format":"date-time"},"resolvedByUserId":{"type":["string","null"],"format":"uuid"},"createdAt":{"type":"string","format":"date-time"},"isSystemGenerated":{"type":"boolean","description":"True when PreStartGo raised the alert (a failed pre-start, a zone, speed, movement, dwell, fuel or inactivity rule) rather than a person. Its title, severity and metadata cannot be edited."}},"required":["id","title","description","status","severity","equipment","user","acknowledgedAt","acknowledgedByUserId","resolvedAt","resolvedByUserId","createdAt"],"description":"Alert list item response"}},"meta":{"type":"object","properties":{"limit":{"type":"number"},"hasMore":{"type":"boolean"},"nextCursor":{"type":["string","null"]},"server_time":{"type":"integer"}},"required":["limit","hasMore","nextCursor"]}},"required":["success","data","meta"],"description":"Cursor-paginated API success response"}}}}}},"post":{"operationId":"createAlert","summary":"Create alert","description":"Creates a new alert manually. Typically alerts are system-generated, but managers can create them directly.","tags":["Alerts"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"equipmentId":{"type":"string","format":"uuid"},"userId":{"type":"string","format":"uuid"},"title":{"type":"string","minLength":1,"maxLength":255},"description":{"type":"string","minLength":1,"maxLength":2000},"severity":{"type":"string","enum":["LOW","MEDIUM","HIGH","CRITICAL"]},"metadata":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}},"required":["title","description","severity"],"additionalProperties":false,"description":"Create a new alert"}}}},"responses":{"201":{"description":"Alert created","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"title":{"type":"string"},"description":{"type":"string"},"status":{"type":"string","enum":["ACTIVE","ACKNOWLEDGED","RESOLVED","DISMISSED"]},"severity":{"type":"string","enum":["LOW","MEDIUM","HIGH","CRITICAL"]},"metadata":{"type":["object","null"],"additionalProperties":{}},"equipment":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"}},"required":["id","name"],"description":"Related equipment"},"user":{"type":["object","null"],"properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"Person who triggered the alert"},"acknowledgedAt":{"type":["string","null"],"format":"date-time"},"acknowledgedByUserId":{"type":["string","null"],"format":"uuid"},"resolvedAt":{"type":["string","null"],"format":"date-time"},"resolvedByUserId":{"type":["string","null"],"format":"uuid"},"createdAt":{"type":"string","format":"date-time"},"isSystemGenerated":{"type":"boolean","description":"True when PreStartGo raised the alert (a failed pre-start, a zone, speed, movement, dwell, fuel or inactivity rule) rather than a person. Its title, severity and metadata cannot be edited."}},"required":["id","title","description","status","severity","equipment","user","acknowledgedAt","acknowledgedByUserId","resolvedAt","resolvedByUserId","createdAt"],"description":"Alert list item response"}},"required":["success","data"],"description":"Standard API success response"}}}}}}},"/api/v1/alerts/:id":{"get":{"operationId":"getAlert","summary":"Get alert","description":"Returns full details of a single alert by ID.","tags":["Alerts"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Alert details","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"title":{"type":"string"},"description":{"type":"string"},"status":{"type":"string","enum":["ACTIVE","ACKNOWLEDGED","RESOLVED","DISMISSED"]},"severity":{"type":"string","enum":["LOW","MEDIUM","HIGH","CRITICAL"]},"metadata":{"type":["object","null"],"additionalProperties":{}},"equipment":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"}},"required":["id","name"],"description":"Related equipment"},"user":{"type":["object","null"],"properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"Person who triggered the alert"},"acknowledgedAt":{"type":["string","null"],"format":"date-time"},"acknowledgedByUserId":{"type":["string","null"],"format":"uuid"},"resolvedAt":{"type":["string","null"],"format":"date-time"},"resolvedByUserId":{"type":["string","null"],"format":"uuid"},"createdAt":{"type":"string","format":"date-time"},"isSystemGenerated":{"type":"boolean","description":"True when PreStartGo raised the alert (a failed pre-start, a zone, speed, movement, dwell, fuel or inactivity rule) rather than a person. Its title, severity and metadata cannot be edited."}},"required":["id","title","description","status","severity","equipment","user","acknowledgedAt","acknowledgedByUserId","resolvedAt","resolvedByUserId","createdAt"],"description":"Alert list item response"}},"required":["success","data"],"description":"Standard API success response"}}}},"404":{"description":"Alert not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}},"patch":{"operationId":"updateAlert","summary":"Update alert","description":"Updates an alert's title, description, severity or metadata. On a system-raised alert (`isSystemGenerated`) only the description can change.","tags":["Alerts"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":255},"description":{"type":"string","minLength":1,"maxLength":2000},"severity":{"type":"string","enum":["LOW","MEDIUM","HIGH","CRITICAL"]},"metadata":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}},"additionalProperties":false,"description":"Update an existing alert"}}}},"responses":{"200":{"description":"Alert updated","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"title":{"type":"string"},"description":{"type":"string"},"status":{"type":"string","enum":["ACTIVE","ACKNOWLEDGED","RESOLVED","DISMISSED"]},"severity":{"type":"string","enum":["LOW","MEDIUM","HIGH","CRITICAL"]},"metadata":{"type":["object","null"],"additionalProperties":{}},"equipment":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"}},"required":["id","name"],"description":"Related equipment"},"user":{"type":["object","null"],"properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"Person who triggered the alert"},"acknowledgedAt":{"type":["string","null"],"format":"date-time"},"acknowledgedByUserId":{"type":["string","null"],"format":"uuid"},"resolvedAt":{"type":["string","null"],"format":"date-time"},"resolvedByUserId":{"type":["string","null"],"format":"uuid"},"createdAt":{"type":"string","format":"date-time"},"isSystemGenerated":{"type":"boolean","description":"True when PreStartGo raised the alert (a failed pre-start, a zone, speed, movement, dwell, fuel or inactivity rule) rather than a person. Its title, severity and metadata cannot be edited."}},"required":["id","title","description","status","severity","equipment","user","acknowledgedAt","acknowledgedByUserId","resolvedAt","resolvedByUserId","createdAt"],"description":"Alert list item response"}},"required":["success","data"],"description":"Standard API success response"}}}},"404":{"description":"Alert not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}},"422":{"description":"A title, severity or metadata edit on a system-raised alert (`alert.system_fields_locked`)","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}}},"/api/v1/alerts/:id/acknowledge":{"post":{"operationId":"acknowledgeAlert","summary":"Acknowledge alert","description":"Marks an alert as acknowledged by the current user, indicating it has been seen and is being handled.","tags":["Alerts"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"responses":{"200":{"description":"Alert acknowledged","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"title":{"type":"string"},"description":{"type":"string"},"status":{"type":"string","enum":["ACTIVE","ACKNOWLEDGED","RESOLVED","DISMISSED"]},"severity":{"type":"string","enum":["LOW","MEDIUM","HIGH","CRITICAL"]},"metadata":{"type":["object","null"],"additionalProperties":{}},"equipment":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"}},"required":["id","name"],"description":"Related equipment"},"user":{"type":["object","null"],"properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"Person who triggered the alert"},"acknowledgedAt":{"type":["string","null"],"format":"date-time"},"acknowledgedByUserId":{"type":["string","null"],"format":"uuid"},"resolvedAt":{"type":["string","null"],"format":"date-time"},"resolvedByUserId":{"type":["string","null"],"format":"uuid"},"createdAt":{"type":"string","format":"date-time"},"isSystemGenerated":{"type":"boolean","description":"True when PreStartGo raised the alert (a failed pre-start, a zone, speed, movement, dwell, fuel or inactivity rule) rather than a person. Its title, severity and metadata cannot be edited."}},"required":["id","title","description","status","severity","equipment","user","acknowledgedAt","acknowledgedByUserId","resolvedAt","resolvedByUserId","createdAt"],"description":"Alert list item response"}},"required":["success","data"],"description":"Standard API success response"}}}},"404":{"description":"Alert not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}}},"/api/v1/alerts/:id/resolve":{"post":{"operationId":"resolveAlert","summary":"Resolve alert","description":"Marks an alert as resolved, indicating the underlying issue has been addressed.","tags":["Alerts"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"responses":{"200":{"description":"Alert resolved","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"title":{"type":"string"},"description":{"type":"string"},"status":{"type":"string","enum":["ACTIVE","ACKNOWLEDGED","RESOLVED","DISMISSED"]},"severity":{"type":"string","enum":["LOW","MEDIUM","HIGH","CRITICAL"]},"metadata":{"type":["object","null"],"additionalProperties":{}},"equipment":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"}},"required":["id","name"],"description":"Related equipment"},"user":{"type":["object","null"],"properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"Person who triggered the alert"},"acknowledgedAt":{"type":["string","null"],"format":"date-time"},"acknowledgedByUserId":{"type":["string","null"],"format":"uuid"},"resolvedAt":{"type":["string","null"],"format":"date-time"},"resolvedByUserId":{"type":["string","null"],"format":"uuid"},"createdAt":{"type":"string","format":"date-time"},"isSystemGenerated":{"type":"boolean","description":"True when PreStartGo raised the alert (a failed pre-start, a zone, speed, movement, dwell, fuel or inactivity rule) rather than a person. Its title, severity and metadata cannot be edited."}},"required":["id","title","description","status","severity","equipment","user","acknowledgedAt","acknowledgedByUserId","resolvedAt","resolvedByUserId","createdAt"],"description":"Alert list item response"}},"required":["success","data"],"description":"Standard API success response"}}}},"404":{"description":"Alert not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}}},"/api/v1/alerts/:id/transition":{"post":{"operationId":"transitionAlert","summary":"Transition alert status","description":"Advances an alert to a new status. Each transition is validated against the state machine and recorded in the audit trail.","tags":["Alerts"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"toStatus":{"type":"string","enum":["ACTIVE","ACKNOWLEDGED","RESOLVED","DISMISSED"]},"notes":{"type":"string","maxLength":2000}},"required":["toStatus"],"additionalProperties":false,"description":"Transition an alert status"}}}},"responses":{"200":{"description":"Alert transitioned","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"title":{"type":"string"},"description":{"type":"string"},"status":{"type":"string","enum":["ACTIVE","ACKNOWLEDGED","RESOLVED","DISMISSED"]},"severity":{"type":"string","enum":["LOW","MEDIUM","HIGH","CRITICAL"]},"metadata":{"type":["object","null"],"additionalProperties":{}},"equipment":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"}},"required":["id","name"],"description":"Related equipment"},"user":{"type":["object","null"],"properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"Person who triggered the alert"},"acknowledgedAt":{"type":["string","null"],"format":"date-time"},"acknowledgedByUserId":{"type":["string","null"],"format":"uuid"},"resolvedAt":{"type":["string","null"],"format":"date-time"},"resolvedByUserId":{"type":["string","null"],"format":"uuid"},"createdAt":{"type":"string","format":"date-time"},"isSystemGenerated":{"type":"boolean","description":"True when PreStartGo raised the alert (a failed pre-start, a zone, speed, movement, dwell, fuel or inactivity rule) rather than a person. Its title, severity and metadata cannot be edited."}},"required":["id","title","description","status","severity","equipment","user","acknowledgedAt","acknowledgedByUserId","resolvedAt","resolvedByUserId","createdAt"],"description":"Alert list item response"}},"required":["success","data"],"description":"Standard API success response"}}}},"404":{"description":"Alert not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}}},"/api/v1/alerts/:id/dismiss":{"post":{"operationId":"dismissAlert","summary":"Dismiss alert","description":"Dismisses an alert without resolving it. Used for false positives or alerts that no longer require action.","tags":["Alerts"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"responses":{"200":{"description":"Alert dismissed","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"title":{"type":"string"},"description":{"type":"string"},"status":{"type":"string","enum":["ACTIVE","ACKNOWLEDGED","RESOLVED","DISMISSED"]},"severity":{"type":"string","enum":["LOW","MEDIUM","HIGH","CRITICAL"]},"metadata":{"type":["object","null"],"additionalProperties":{}},"equipment":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"}},"required":["id","name"],"description":"Related equipment"},"user":{"type":["object","null"],"properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"Person who triggered the alert"},"acknowledgedAt":{"type":["string","null"],"format":"date-time"},"acknowledgedByUserId":{"type":["string","null"],"format":"uuid"},"resolvedAt":{"type":["string","null"],"format":"date-time"},"resolvedByUserId":{"type":["string","null"],"format":"uuid"},"createdAt":{"type":"string","format":"date-time"},"isSystemGenerated":{"type":"boolean","description":"True when PreStartGo raised the alert (a failed pre-start, a zone, speed, movement, dwell, fuel or inactivity rule) rather than a person. Its title, severity and metadata cannot be edited."}},"required":["id","title","description","status","severity","equipment","user","acknowledgedAt","acknowledgedByUserId","resolvedAt","resolvedByUserId","createdAt"],"description":"Alert list item response"}},"required":["success","data"],"description":"Standard API success response"}}}},"404":{"description":"Alert not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}}},"/api/v1/telemetry/events":{"get":{"operationId":"listTimEvents","summary":"Query telemetry events","description":"Returns a paginated list of telemetry events such as ignition changes, relay state transitions, and heartbeats.","tags":["Telemetry"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","maxLength":500},"required":false,"name":"after","in":"query"},{"schema":{"type":"string","format":"uuid"},"required":false,"name":"equipmentId","in":"query"},{"schema":{"type":"string","format":"uuid"},"required":false,"name":"deviceId","in":"query"},{"schema":{"type":["string","null"],"format":"date-time"},"required":false,"name":"from","in":"query"},{"schema":{"type":["string","null"],"format":"date-time"},"required":false,"name":"to","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":50},"required":false,"name":"type","in":"query"}],"responses":{"200":{"description":"List of telemetry events","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"orgId":{"type":"string","format":"uuid"},"equipmentId":{"type":"string","format":"uuid"},"deviceId":{"type":"string","format":"uuid"},"type":{"type":"string","minLength":1,"maxLength":50},"payload":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},"latitude":{"type":["number","null"],"minimum":-90,"maximum":90,"description":"WGS-84 latitude in decimal degrees (-90 to 90)"},"longitude":{"type":["number","null"],"minimum":-180,"maximum":180,"description":"WGS-84 longitude in decimal degrees (-180 to 180)"},"altitude":{"type":["number","null"],"minimum":-500,"maximum":10000},"speed":{"type":["number","null"],"minimum":0,"maximum":500},"heading":{"type":["number","null"],"minimum":0,"exclusiveMaximum":360},"accuracy":{"type":["number","null"],"minimum":0,"maximum":1000},"batteryVoltage":{"type":["number","null"],"minimum":0,"maximum":50},"externalVoltage":{"type":["number","null"],"minimum":0,"maximum":50},"rssi":{"type":["integer","null"],"minimum":-120,"maximum":0},"sourceSeqNo":{"type":["integer","null"]},"timestamp":{"type":["string","null"],"format":"date-time"},"createdAt":{"type":["string","null"],"format":"date-time"}},"required":["id","orgId","equipmentId","deviceId","type","payload","timestamp","createdAt"],"description":"Tracker (`deviceType: TM`) telemetry event (append-only)"}},"meta":{"type":"object","properties":{"limit":{"type":"number"},"hasMore":{"type":"boolean"},"nextCursor":{"type":["string","null"]},"server_time":{"type":"integer"}},"required":["limit","hasMore","nextCursor"]}},"required":["success","data","meta"],"description":"Cursor-paginated API success response"}}}}}}},"/api/v1/telemetry/state/:deviceId":{"get":{"operationId":"getTimState","summary":"Get current telemetry state for a Tracker","description":"Retrieves the latest known state of a Tracker (`deviceType: TM`) including relay position, ignition, battery, and signal strength.","tags":["Telemetry"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"deviceId","in":"path"}],"responses":{"200":{"description":"Telemetry state","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"deviceId":{"type":"string","format":"uuid"},"orgId":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["ONLINE","OFFLINE","NEVER_CONNECTED"]},"lastSeenAt":{"type":["string","null"],"format":"date-time"},"latitude":{"type":["number","null"],"minimum":-90,"maximum":90,"description":"WGS-84 latitude in decimal degrees (-90 to 90)"},"longitude":{"type":["number","null"],"minimum":-180,"maximum":180,"description":"WGS-84 longitude in decimal degrees (-180 to 180)"},"batteryVoltage":{"type":["number","null"],"minimum":0,"maximum":50},"externalVoltage":{"type":["number","null"],"minimum":0,"maximum":50},"isIgnitionOn":{"type":"boolean"},"isMoving":{"type":"boolean"},"imei":{"type":["string","null"],"pattern":"^\\d{15}$"},"iccid":{"type":["string","null"],"maxLength":25},"lastSpeed":{"type":["number","null"],"minimum":0,"maximum":500},"lastHeading":{"type":["number","null"],"minimum":0,"exclusiveMaximum":360},"rssi":{"type":["integer","null"],"minimum":-120,"maximum":0},"firmwareVersion":{"type":["string","null"],"maxLength":50},"certificateExpiresAt":{"type":["string","null"],"format":"date-time"},"createdAt":{"type":["string","null"],"format":"date-time"},"updatedAt":{"type":["string","null"],"format":"date-time"}},"required":["id","deviceId","orgId","status","isIgnitionOn","isMoving","createdAt","updatedAt"],"description":"Current telemetry device state as returned to API clients"}},"required":["success","data"],"description":"Standard API success response"}}}},"404":{"description":"Telemetry state not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}}},"/api/v1/telemetry/equipment/:equipmentId/history":{"get":{"operationId":"getEquipmentTelemetryHistory","summary":"Get equipment event history","description":"Returns a paginated timeline of telemetry events for a specific equipment item, useful for operational auditing.","tags":["Telemetry"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"equipmentId","in":"path"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","maxLength":500},"required":false,"name":"after","in":"query"},{"schema":{"type":["string","null"],"format":"date-time"},"required":false,"name":"from","in":"query"},{"schema":{"type":["string","null"],"format":"date-time"},"required":false,"name":"to","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":50},"required":false,"name":"type","in":"query"}],"responses":{"200":{"description":"Equipment event history","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"orgId":{"type":"string","format":"uuid"},"equipmentId":{"type":"string","format":"uuid"},"deviceId":{"type":"string","format":"uuid"},"type":{"type":"string","minLength":1,"maxLength":50},"payload":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},"latitude":{"type":["number","null"],"minimum":-90,"maximum":90,"description":"WGS-84 latitude in decimal degrees (-90 to 90)"},"longitude":{"type":["number","null"],"minimum":-180,"maximum":180,"description":"WGS-84 longitude in decimal degrees (-180 to 180)"},"altitude":{"type":["number","null"],"minimum":-500,"maximum":10000},"speed":{"type":["number","null"],"minimum":0,"maximum":500},"heading":{"type":["number","null"],"minimum":0,"exclusiveMaximum":360},"accuracy":{"type":["number","null"],"minimum":0,"maximum":1000},"batteryVoltage":{"type":["number","null"],"minimum":0,"maximum":50},"externalVoltage":{"type":["number","null"],"minimum":0,"maximum":50},"rssi":{"type":["integer","null"],"minimum":-120,"maximum":0},"sourceSeqNo":{"type":["integer","null"]},"timestamp":{"type":["string","null"],"format":"date-time"},"createdAt":{"type":["string","null"],"format":"date-time"}},"required":["id","orgId","equipmentId","deviceId","type","payload","timestamp","createdAt"],"description":"Tracker (`deviceType: TM`) telemetry event (append-only)"}},"meta":{"type":"object","properties":{"limit":{"type":"number"},"hasMore":{"type":"boolean"},"nextCursor":{"type":["string","null"]},"server_time":{"type":"integer"}},"required":["limit","hasMore","nextCursor"]}},"required":["success","data","meta"],"description":"Cursor-paginated API success response"}}}}}}},"/api/v1/telemetry/tims/:id/location/history":{"get":{"operationId":"getTimLocationHistory","summary":"Get telemetry location history","description":"Returns GPS location history from telemetry events.","tags":["Telemetry"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","maxLength":500},"required":false,"name":"after","in":"query"},{"schema":{"type":["string","null"],"format":"date-time"},"required":false,"name":"from","in":"query"},{"schema":{"type":["string","null"],"format":"date-time"},"required":false,"name":"to","in":"query"}],"responses":{"200":{"description":"Telemetry location history","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"type":"object","properties":{"latitude":{"type":"number","minimum":-90,"maximum":90,"description":"WGS-84 latitude in decimal degrees (-90 to 90)"},"longitude":{"type":"number","minimum":-180,"maximum":180,"description":"WGS-84 longitude in decimal degrees (-180 to 180)"},"altitude":{"type":["number","null"],"minimum":-500,"maximum":10000},"speed":{"type":["number","null"],"minimum":0,"maximum":500},"heading":{"type":["number","null"],"minimum":0,"exclusiveMaximum":360},"accuracy":{"type":["number","null"],"minimum":0,"maximum":1000},"timestamp":{"type":["string","null"],"format":"date-time"}},"required":["latitude","longitude","timestamp"],"description":"Individual GPS location data point"}},"meta":{"type":"object","properties":{"limit":{"type":"number"},"hasMore":{"type":"boolean"},"nextCursor":{"type":["string","null"]},"server_time":{"type":"integer"}},"required":["limit","hasMore","nextCursor"]}},"required":["success","data","meta"],"description":"Cursor-paginated API success response"}}}}}}},"/api/v1/utilization/equipment/:equipmentId":{"get":{"operationId":"getEquipmentUtilization","summary":"Get equipment utilization","description":"Returns bucketed utilization data for an equipment item, aggregated by the specified granularity (hour, day, or week).","tags":["Utilization"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"equipmentId","in":"path"},{"schema":{"type":["string","null"],"format":"date-time"},"required":false,"name":"from","in":"query"},{"schema":{"type":["string","null"],"format":"date-time"},"required":false,"name":"to","in":"query"},{"schema":{"type":"string","enum":["HOUR","DAY","WEEK"],"default":"DAY"},"required":false,"name":"granularity","in":"query"}],"responses":{"200":{"description":"Equipment utilization data","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"equipmentId":{"type":"string","format":"uuid"},"from":{"type":"string"},"to":{"type":"string"},"granularity":{"type":"string","enum":["HOUR","DAY","WEEK"]},"buckets":{"type":"array","items":{"type":"object","properties":{"periodStart":{"type":"string"},"totalMinutes":{"type":"number"},"movingMinutes":{"type":"number"},"stationaryMinutes":{"type":"number"},"utilizationPercent":{"type":"number"},"avgSpeedKmh":{"type":"number"},"maxSpeedKmh":{"type":"number"},"readingCount":{"type":"number"}},"required":["periodStart","totalMinutes","movingMinutes","stationaryMinutes","utilizationPercent","avgSpeedKmh","maxSpeedKmh","readingCount"],"description":"Time-bucketed utilization metrics"}},"summary":{"type":"object","properties":{"totalMinutes":{"type":"number"},"movingMinutes":{"type":"number"},"stationaryMinutes":{"type":"number"},"utilizationPercent":{"type":"number"},"avgSpeedKmh":{"type":"number"},"maxSpeedKmh":{"type":"number"}},"required":["totalMinutes","movingMinutes","stationaryMinutes","utilizationPercent","avgSpeedKmh","maxSpeedKmh"]}},"required":["equipmentId","from","to","granularity","buckets","summary"],"description":"Equipment utilization response"}},"required":["success","data"],"description":"Standard API success response"}}}}}}},"/api/v1/utilization/fleet":{"get":{"operationId":"getFleetUtilization","summary":"Get fleet utilization summary","description":"Returns fleet-wide utilization metrics including average utilization, underutilized equipment, and top idlers.","tags":["Utilization"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":["string","null"],"format":"date-time"},"required":false,"name":"from","in":"query"},{"schema":{"type":["string","null"],"format":"date-time"},"required":false,"name":"to","in":"query"},{"schema":{"type":"string","format":"uuid"},"required":false,"name":"siteId","in":"query"}],"responses":{"200":{"description":"Fleet utilization summary","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"from":{"type":"string"},"to":{"type":"string"},"avgUtilizationPercent":{"type":"number"},"totalEquipment":{"type":"number"},"totalDistanceKm":{"type":"number"},"underutilizedCount":{"type":"number"},"underutilized":{"type":"array","items":{"type":"object","properties":{"equipmentId":{"type":"string","format":"uuid"},"equipmentName":{"type":"string"},"siteName":{"type":["string","null"]},"utilizationPercent":{"type":"number"},"totalMinutes":{"type":"number"},"movingMinutes":{"type":"number"}},"required":["equipmentId","equipmentName","siteName","utilizationPercent","totalMinutes","movingMinutes"],"description":"Underutilized equipment entry"}},"topIdlers":{"type":"array","items":{"type":"object","properties":{"equipmentId":{"type":"string","format":"uuid"},"equipmentName":{"type":"string"},"siteName":{"type":["string","null"]},"utilizationPercent":{"type":"number"},"totalMinutes":{"type":"number"},"movingMinutes":{"type":"number"}},"required":["equipmentId","equipmentName","siteName","utilizationPercent","totalMinutes","movingMinutes"],"description":"Underutilized equipment entry"}}},"required":["from","to","avgUtilizationPercent","totalEquipment","totalDistanceKm","underutilizedCount","underutilized","topIdlers"],"description":"Fleet utilization summary response"}},"required":["success","data"],"description":"Standard API success response"}}}}}}},"/api/v1/utilization/equipment/:equipmentId/distance":{"get":{"operationId":"getEquipmentDistance","summary":"Get equipment distance traveled","description":"Returns the total distance traveled by an equipment item over the specified period, calculated using GPS telemetry data.","tags":["Utilization"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"equipmentId","in":"path"},{"schema":{"type":["string","null"],"format":"date-time"},"required":false,"name":"from","in":"query"},{"schema":{"type":["string","null"],"format":"date-time"},"required":false,"name":"to","in":"query"}],"responses":{"200":{"description":"Distance traveled","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"equipmentId":{"type":"string","format":"uuid"},"from":{"type":"string"},"to":{"type":"string"},"totalDistanceKm":{"type":"number"},"pointCount":{"type":"number"}},"required":["equipmentId","from","to","totalDistanceKm","pointCount"],"description":"Distance traveled response"}},"required":["success","data"],"description":"Standard API success response"}}}}}}},"/api/v1/tags":{"get":{"operationId":"listTags","summary":"List tags","description":"Returns a cursor-paginated list of tags registered to the org. Tags are physical stickers (QR + NFC) used for field identification of equipment.","tags":["Tags"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","maxLength":500},"required":false,"name":"after","in":"query"},{"schema":{"type":"string","maxLength":100},"required":false,"name":"search","in":"query"},{"schema":{"type":"string","format":"uuid"},"required":false,"name":"equipmentId","in":"query"},{"schema":{"type":"boolean"},"required":false,"name":"isActive","in":"query"},{"schema":{"type":"boolean"},"required":false,"name":"isAssigned","in":"query"},{"schema":{"type":"string","enum":["ALLOCATED","AVAILABLE","INSTALLED","RETIRED"]},"required":false,"name":"state","in":"query"}],"responses":{"200":{"description":"List of tags","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"code":{"type":"string"},"nfcId":{"type":["string","null"]},"equipment":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"}},"required":["id","name"],"description":"Linked equipment"},"isActive":{"type":"boolean"},"state":{"type":["string","null"],"enum":["ALLOCATED","AVAILABLE","INSTALLED","RETIRED",null]},"status":{"type":["string","null"]},"batchLetterTriple":{"type":["string","null"],"minLength":3,"maxLength":3},"registeredAt":{"type":["string","null"],"format":"date-time"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","code","nfcId","equipment","isActive","state","status","batchLetterTriple","registeredAt","createdAt"],"description":"Tag list item response"}},"meta":{"type":"object","properties":{"limit":{"type":"number"},"hasMore":{"type":"boolean"},"nextCursor":{"type":["string","null"]},"server_time":{"type":"integer"}},"required":["limit","hasMore","nextCursor"]}},"required":["success","data","meta"],"description":"Cursor-paginated API success response"}}}}}}},"/api/v1/tags/export":{"get":{"operationId":"exportTags","summary":"Export tags","description":"Download tags as CSV or XLSX file.","tags":["Tags"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","enum":["csv","xlsx"],"default":"csv"},"required":false,"name":"format","in":"query"},{"schema":{"type":"string","maxLength":100},"required":false,"name":"search","in":"query"},{"schema":{"type":"boolean"},"required":false,"name":"isActive","in":"query"},{"schema":{"type":"boolean"},"required":false,"name":"isAssigned","in":"query"},{"schema":{"type":"string","enum":["ALLOCATED","AVAILABLE","INSTALLED","RETIRED"]},"required":false,"name":"state","in":"query"},{"schema":{"type":"string","format":"uuid","description":"Only the tags fitted to this equipment"},"required":false,"description":"Only the tags fitted to this equipment","name":"equipmentId","in":"query"}],"responses":{"200":{"description":"File download","content":{"application/octet-stream":{"schema":{"type":"string"}}}},"202":{"description":"Row count exceeds 10000 — generation queued as a background job. Retain `data.jobId` and poll `GET /api/v1/tags/export/jobs/{jobId}` until `status` is `COMPLETED`, then download `fileUrl` (a short-lived signed URL, re-signed on each poll). Completion is not announced by any other channel.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"jobId":{"type":"string","format":"uuid"},"resource":{"type":"string"},"format":{"type":"string","enum":["csv","xlsx"]},"status":{"type":"string","enum":["PENDING","GENERATING","COMPLETED","FAILED"]},"rowCount":{"type":["integer","null"],"minimum":0},"fileUrl":{"type":["string","null"],"maxLength":2048,"format":"uri"},"fileSize":{"type":["integer","null"],"minimum":0},"errorMessage":{"type":["string","null"],"maxLength":2000},"createdAt":{"type":["string","null"],"format":"date-time"},"updatedAt":{"type":["string","null"],"format":"date-time"},"completedAt":{"type":["string","null"],"format":"date-time"}},"required":["jobId","resource","format","status","createdAt","updatedAt"],"description":"Async resource-export job status"}},"required":["success","data"],"description":"Standard API success response"}}}}}}},"/api/v1/tags/export/jobs/{id}":{"get":{"operationId":"getTagsExportJob","summary":"Get tags export job status","description":"Poll the status of a background export job (returned by GET /export when the row count exceeds 10000). Export files are kept for 30 days; a job past that window returns 404 whether or not the retention sweep has reached it yet.","tags":["Tags"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Export job status","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"jobId":{"type":"string","format":"uuid"},"resource":{"type":"string"},"format":{"type":"string","enum":["csv","xlsx"]},"status":{"type":"string","enum":["PENDING","GENERATING","COMPLETED","FAILED"]},"rowCount":{"type":["integer","null"],"minimum":0},"fileUrl":{"type":["string","null"],"maxLength":2048,"format":"uri"},"fileSize":{"type":["integer","null"],"minimum":0},"errorMessage":{"type":["string","null"],"maxLength":2000},"createdAt":{"type":["string","null"],"format":"date-time"},"updatedAt":{"type":["string","null"],"format":"date-time"},"completedAt":{"type":["string","null"],"format":"date-time"}},"required":["jobId","resource","format","status","createdAt","updatedAt"],"description":"Async resource-export job status"}},"required":["success","data"],"description":"Standard API success response"}}}},"404":{"description":"Export job not found"}}}},"/api/v1/tags/export/template":{"get":{"operationId":"exportTagsTemplate","summary":"Download tags import template","description":"Download an XLSX template with headers, example row, and column descriptions for importing tags.","tags":["Tags"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"XLSX template file","content":{"application/octet-stream":{"schema":{"type":"string"}}}}}}},"/api/v1/tags/import/preview":{"post":{"operationId":"previewTagsImport","summary":"Preview tags import","description":"Parse and validate a CSV/XLSX file for importing tags. Returns a preview with validation results.","tags":["Tags"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"responses":{"200":{"description":"Import preview with validated rows","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"totalRows":{"type":"integer"},"validRows":{"type":"integer"},"errorRows":{"type":"integer"},"rows":{"type":"array","items":{"type":"object","properties":{"rowNumber":{"type":"integer"},"data":{"type":"object","additionalProperties":{}},"valid":{"type":"boolean"},"errors":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"message":{"type":"string"}},"required":["field","message"],"description":"Field-level import validation error"}}},"required":["rowNumber","data","valid","errors"],"description":"Preview row from parsed import file"}},"columns":{"type":"array","items":{"type":"string"}}},"required":["totalRows","validRows","errorRows","rows","columns"],"description":"Import preview with validated rows"}},"required":["success","data"],"description":"Standard API success response"}}}},"400":{"description":"Invalid file"}}}},"/api/v1/tags/import/commit":{"post":{"operationId":"commitTagsImport","summary":"Commit tags import","description":"Insert validated tags rows in a single database transaction.","tags":["Tags"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"rows":{"type":"array","items":{"type":"object","additionalProperties":{}},"minItems":1,"maxItems":10000}},"required":["rows"],"additionalProperties":false,"description":"Commit validated import rows"}}}},"responses":{"201":{"description":"Import commit result","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"imported":{"type":"integer"},"resource":{"type":"string"}},"required":["imported","resource"],"description":"Import commit result"}},"required":["success","data"],"description":"Standard API success response"}}}},"422":{"description":"One or more rows failed re-validation at commit time","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["IMPORT_VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":["string","null"]}},"required":["code","message","requestId"]}},"required":["success","error"]}}}}}}},"/api/v1/tags/:id":{"get":{"operationId":"getTag","summary":"Get tag details","description":"Returns full details of a tag, including its assigned equipment if any.","tags":["Tags"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Tag details","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"code":{"type":"string"},"nfcId":{"type":["string","null"]},"equipment":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"}},"required":["id","name"],"description":"Linked equipment"},"isActive":{"type":"boolean"},"state":{"type":["string","null"],"enum":["ALLOCATED","AVAILABLE","INSTALLED","RETIRED",null]},"status":{"type":["string","null"]},"batchLetterTriple":{"type":["string","null"],"minLength":3,"maxLength":3},"registeredAt":{"type":["string","null"],"format":"date-time"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","code","nfcId","equipment","isActive","state","status","batchLetterTriple","registeredAt","createdAt"],"description":"Tag list item response"}},"required":["success","data"],"description":"Standard API success response"}}}},"404":{"description":"Tag not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}}},"/api/v1/tags/lookup/:code":{"get":{"operationId":"lookupTag","summary":"Lookup tag by code (for scanning)","description":"Resolves a tag by its T-LLL-NNNC serial code. Used by the mobile app after scanning a QR code or tapping an NFC tag in the field.","tags":["Tags"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"code","in":"path"}],"responses":{"200":{"description":"Tag details","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"code":{"type":"string"},"nfcId":{"type":["string","null"]},"equipment":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"}},"required":["id","name"],"description":"Linked equipment"},"isActive":{"type":"boolean"},"state":{"type":["string","null"],"enum":["ALLOCATED","AVAILABLE","INSTALLED","RETIRED",null]},"status":{"type":["string","null"]},"batchLetterTriple":{"type":["string","null"],"minLength":3,"maxLength":3},"registeredAt":{"type":["string","null"],"format":"date-time"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","code","nfcId","equipment","isActive","state","status","batchLetterTriple","registeredAt","createdAt"],"description":"Tag list item response"}},"required":["success","data"],"description":"Standard API success response"}}}},"404":{"description":"Tag not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}}},"/api/v1/services/export/jobs/{id}":{"get":{"operationId":"getServicesExportJob","summary":"Get services export job status","description":"Poll the status of a background export job (returned by GET /export when the row count exceeds 10000). Export files are kept for 30 days; a job past that window returns 404 whether or not the retention sweep has reached it yet.","tags":["Services"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Export job status","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"jobId":{"type":"string","format":"uuid"},"resource":{"type":"string"},"format":{"type":"string","enum":["csv","xlsx"]},"status":{"type":"string","enum":["PENDING","GENERATING","COMPLETED","FAILED"]},"rowCount":{"type":["integer","null"],"minimum":0},"fileUrl":{"type":["string","null"],"maxLength":2048,"format":"uri"},"fileSize":{"type":["integer","null"],"minimum":0},"errorMessage":{"type":["string","null"],"maxLength":2000},"createdAt":{"type":["string","null"],"format":"date-time"},"updatedAt":{"type":["string","null"],"format":"date-time"},"completedAt":{"type":["string","null"],"format":"date-time"}},"required":["jobId","resource","format","status","createdAt","updatedAt"],"description":"Async resource-export job status"}},"required":["success","data"],"description":"Standard API success response"}}}},"404":{"description":"Export job not found"}}}},"/api/v1/services":{"get":{"operationId":"listServices","summary":"List services","description":"Returns a paginated list of services for the authenticated org, filterable by status and equipment.","tags":["Services"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","maxLength":500},"required":false,"name":"after","in":"query"},{"schema":{"type":"string","enum":["UPCOMING","IN_PROGRESS","COMPLETED","CANCELED"]},"required":false,"name":"status","in":"query"},{"schema":{"type":"string","enum":["LOW","MEDIUM","HIGH","URGENT"]},"required":false,"name":"priority","in":"query"},{"schema":{"type":"string","format":"uuid"},"required":false,"name":"siteId","in":"query"},{"schema":{"type":"string","format":"uuid"},"required":false,"name":"equipmentId","in":"query"},{"schema":{"type":"string","format":"uuid"},"required":false,"name":"assignedToUserId","in":"query"},{"schema":{"type":"string","enum":["PREDICTIVE","AD_HOC","DEFECT_REPAIR"]},"required":false,"name":"trigger","in":"query"},{"schema":{"type":"string","enum":["ROUTINE","REPAIR","INSPECTION","MODIFICATION","CERTIFICATION","OTHER"]},"required":false,"name":"serviceType","in":"query"},{"schema":{"type":"string","format":"uuid","description":"Only services linked to this defect"},"required":false,"description":"Only services linked to this defect","name":"defectId","in":"query"},{"schema":{"type":"string","maxLength":100},"required":false,"name":"search","in":"query"},{"schema":{"type":["string","null"],"format":"date-time"},"required":false,"name":"from","in":"query"},{"schema":{"type":["string","null"],"format":"date-time"},"required":false,"name":"to","in":"query"}],"responses":{"200":{"description":"List of services","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"equipmentId":{"type":"string","format":"uuid"},"equipmentName":{"type":["string","null"]},"trigger":{"type":"string","enum":["PREDICTIVE","AD_HOC","DEFECT_REPAIR"]},"serviceType":{"type":"string","enum":["ROUTINE","REPAIR","INSPECTION","MODIFICATION","CERTIFICATION","OTHER"]},"priority":{"type":"string","enum":["LOW","MEDIUM","HIGH","URGENT"]},"status":{"type":"string","enum":["UPCOMING","IN_PROGRESS","COMPLETED","CANCELED"]},"title":{"type":["string","null"]},"description":{"type":["string","null"]},"assignedToName":{"type":["string","null"]},"assignedTo":{"type":["object","null"],"properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"A person: the name this org shows for them, where that name came from, and the contact that tells two same-named people apart"},"performedByName":{"type":["string","null"]},"performedBy":{"type":["object","null"],"properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"A person: the name this org shows for them, where that name came from, and the contact that tells two same-named people apart"},"scheduledDate":{"type":["string","null"],"format":"date-time"},"dueDate":{"type":["string","null"],"format":"date-time"},"completedAt":{"type":["string","null"],"format":"date-time"},"completionNotes":{"type":["string","null"]},"estimatedCost":{"type":["number","null"],"minimum":0,"maximum":9999999999.99},"actualCost":{"type":["number","null"],"minimum":0,"maximum":9999999999.99},"createdAt":{"type":"string","format":"date-time"},"defectId":{"type":["string","null"],"format":"uuid","description":"The defect this service repairs (set on a DEFECT_REPAIR service). Null when there is none."}},"required":["id","equipmentId","equipmentName","trigger","serviceType","priority","status","title","description","assignedToName","assignedTo","performedByName","performedBy","scheduledDate","dueDate","completedAt","completionNotes","estimatedCost","actualCost","createdAt"],"description":"Service list item response"}},"meta":{"type":"object","properties":{"limit":{"type":"number"},"hasMore":{"type":"boolean"},"nextCursor":{"type":["string","null"]},"server_time":{"type":"integer"}},"required":["limit","hasMore","nextCursor"]}},"required":["success","data","meta"],"description":"Cursor-paginated API success response"}}}}}},"post":{"operationId":"createService","summary":"Create service","description":"Creates a new service for equipment. Only the owner org can create service records.","tags":["Services"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"equipmentId":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["UPCOMING","COMPLETED"]},"trigger":{"type":"string","enum":["PREDICTIVE","AD_HOC","DEFECT_REPAIR"]},"serviceType":{"type":"string","enum":["ROUTINE","REPAIR","INSPECTION","MODIFICATION","CERTIFICATION","OTHER"]},"priority":{"type":"string","enum":["LOW","MEDIUM","HIGH","URGENT"]},"title":{"type":"string","minLength":1,"maxLength":255},"description":{"type":"string","maxLength":2000},"defectId":{"type":"string","format":"uuid","description":"The defect this service repairs (required when `trigger` is DEFECT_REPAIR): a defect on the serviced equipment."},"checklistTemplateId":{"type":["string","null"],"format":"uuid","description":"The SERVICE checklist to complete this service against: an active SERVICE template of your organization. Omit it, or send null, for no checklist; GET /services/checklist-default answers the machine's default service checklist, to send here. Refused on a service created as COMPLETED, which carries no checklist answers."},"assignedToUserId":{"type":"string","format":"uuid"},"assignedToName":{"type":"string","minLength":1,"maxLength":255},"assignedToCompany":{"type":"string","minLength":1,"maxLength":255},"scheduledDate":{"type":"string","format":"date-time"},"dueDate":{"type":"string","format":"date-time"},"estimatedCost":{"type":"number","minimum":0,"maximum":9999999999.99},"completedAt":{"type":"string","format":"date-time"},"completionNotes":{"type":"string","maxLength":2000},"performedByName":{"type":"string","minLength":1,"maxLength":255},"performedByCompany":{"type":"string","minLength":1,"maxLength":255},"hoursAtService":{"type":"integer","minimum":0},"kmAtService":{"type":"integer","minimum":0},"actualCost":{"type":"number","minimum":0,"maximum":9999999999.99},"invoiceNumber":{"type":"string","maxLength":100},"nextServiceHours":{"type":"integer","minimum":0},"nextServiceKm":{"type":"integer","minimum":0},"nextServiceDate":{"type":"string","format":"date-time"},"currency":{"type":"string"}},"required":["equipmentId","serviceType"],"additionalProperties":false,"description":"Create a service (upcoming) or log a completed service"}}}},"responses":{"201":{"description":"Service created","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"equipmentId":{"type":"string","format":"uuid"},"equipmentName":{"type":["string","null"]},"trigger":{"type":"string","enum":["PREDICTIVE","AD_HOC","DEFECT_REPAIR"]},"serviceType":{"type":"string","enum":["ROUTINE","REPAIR","INSPECTION","MODIFICATION","CERTIFICATION","OTHER"]},"priority":{"type":"string","enum":["LOW","MEDIUM","HIGH","URGENT"]},"status":{"type":"string","enum":["UPCOMING","IN_PROGRESS","COMPLETED","CANCELED"]},"title":{"type":["string","null"]},"description":{"type":["string","null"]},"assignedToName":{"type":["string","null"]},"assignedTo":{"type":["object","null"],"properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"A person: the name this org shows for them, where that name came from, and the contact that tells two same-named people apart"},"performedByName":{"type":["string","null"]},"performedBy":{"type":["object","null"],"properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"A person: the name this org shows for them, where that name came from, and the contact that tells two same-named people apart"},"scheduledDate":{"type":["string","null"],"format":"date-time"},"dueDate":{"type":["string","null"],"format":"date-time"},"completedAt":{"type":["string","null"],"format":"date-time"},"completionNotes":{"type":["string","null"]},"estimatedCost":{"type":["number","null"],"minimum":0,"maximum":9999999999.99},"actualCost":{"type":["number","null"],"minimum":0,"maximum":9999999999.99},"createdAt":{"type":"string","format":"date-time"},"defectId":{"type":["string","null"],"format":"uuid","description":"The defect this service repairs (set on a DEFECT_REPAIR service). Null when there is none."}},"required":["id","equipmentId","equipmentName","trigger","serviceType","priority","status","title","description","assignedToName","assignedTo","performedByName","performedBy","scheduledDate","dueDate","completedAt","completionNotes","estimatedCost","actualCost","createdAt"],"description":"Service list item response"}},"required":["success","data"],"description":"Standard API success response"}}}}}}},"/api/v1/services/export":{"get":{"operationId":"exportServices","summary":"Export services","description":"Downloads services matching the given filters as a CSV or XLSX file (the same filters as the list endpoint, minus pagination).","tags":["Services"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","enum":["csv","xlsx"],"default":"csv"},"required":false,"name":"format","in":"query"},{"schema":{"type":"string","maxLength":100},"required":false,"name":"search","in":"query"},{"schema":{"type":"string","enum":["UPCOMING","IN_PROGRESS","COMPLETED","CANCELED"]},"required":false,"name":"status","in":"query"},{"schema":{"type":"string","enum":["LOW","MEDIUM","HIGH","URGENT"]},"required":false,"name":"priority","in":"query"},{"schema":{"type":"string","format":"uuid"},"required":false,"name":"siteId","in":"query"},{"schema":{"type":"string","format":"uuid"},"required":false,"name":"equipmentId","in":"query"},{"schema":{"type":"string","format":"uuid"},"required":false,"name":"assignedToUserId","in":"query"},{"schema":{"type":"string","enum":["PREDICTIVE","AD_HOC","DEFECT_REPAIR"]},"required":false,"name":"trigger","in":"query"},{"schema":{"type":"string","enum":["ROUTINE","REPAIR","INSPECTION","MODIFICATION","CERTIFICATION","OTHER"]},"required":false,"name":"serviceType","in":"query"},{"schema":{"type":["string","null"],"format":"date-time"},"required":false,"name":"from","in":"query"},{"schema":{"type":["string","null"],"format":"date-time"},"required":false,"name":"to","in":"query"}],"responses":{"200":{"description":"File download","content":{"application/octet-stream":{"schema":{"type":"string"}}}},"202":{"description":"Row count exceeds the 10000-row inline limit — generation queued as a background job. Retain `data.jobId` and poll `GET /api/v1/services/export/jobs/{jobId}` until `status` is `COMPLETED`, then download `fileUrl` (a short-lived signed URL, re-signed on each poll). Completion is not announced by any other channel.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"jobId":{"type":"string","format":"uuid"},"resource":{"type":"string"},"format":{"type":"string","enum":["csv","xlsx"]},"status":{"type":"string","enum":["PENDING","GENERATING","COMPLETED","FAILED"]},"rowCount":{"type":["integer","null"],"minimum":0},"fileUrl":{"type":["string","null"],"maxLength":2048,"format":"uri"},"fileSize":{"type":["integer","null"],"minimum":0},"errorMessage":{"type":["string","null"],"maxLength":2000},"createdAt":{"type":["string","null"],"format":"date-time"},"updatedAt":{"type":["string","null"],"format":"date-time"},"completedAt":{"type":["string","null"],"format":"date-time"}},"required":["jobId","resource","format","status","createdAt","updatedAt"],"description":"Async resource-export job status"}},"required":["success","data"],"description":"Standard API success response"}}}}}}},"/api/v1/services/checklist-default":{"get":{"operationId":"getServiceChecklistDefault","summary":"Get the default service checklist for a machine","description":"Returns the machine's default SERVICE checklist: its own default service checklist, then its group's. Only active SERVICE templates of your organization are returned. A create does not apply it for you: send it as `checklistTemplateId` (an omitted `checklistTemplateId` means no checklist).","tags":["Services"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","description":"The machine a new service is for"},"required":true,"description":"The machine a new service is for","name":"equipmentId","in":"query"}],"responses":{"200":{"description":"The default service checklist, or null","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"template":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"}},"required":["id","name"],"description":"The checklist a new service on this machine takes when none is chosen"},"source":{"type":["string","null"],"enum":["EQUIPMENT","GROUP",null],"description":"Where the default comes from: the machine's own default or its group's"}},"required":["template","source"],"description":"Default service checklist for a machine"}},"required":["success","data"],"description":"Standard API success response"}}}},"404":{"description":"Equipment not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}}},"/api/v1/services/:id":{"get":{"operationId":"getService","summary":"Get service detail","description":"Retrieves a service with its full transition history showing all status changes, and its service checklist with the recorded answers.","tags":["Services"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Service detail with transitions history","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"equipmentId":{"type":"string","format":"uuid"},"equipmentName":{"type":["string","null"]},"trigger":{"type":"string","enum":["PREDICTIVE","AD_HOC","DEFECT_REPAIR"]},"serviceType":{"type":"string","enum":["ROUTINE","REPAIR","INSPECTION","MODIFICATION","CERTIFICATION","OTHER"]},"priority":{"type":"string","enum":["LOW","MEDIUM","HIGH","URGENT"]},"status":{"type":"string","enum":["UPCOMING","IN_PROGRESS","COMPLETED","CANCELED"]},"title":{"type":["string","null"]},"description":{"type":["string","null"]},"assignedToName":{"type":["string","null"]},"assignedTo":{"type":["object","null"],"properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"A person: the name this org shows for them, where that name came from, and the contact that tells two same-named people apart"},"performedByName":{"type":["string","null"]},"performedBy":{"type":["object","null"],"properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"A person: the name this org shows for them, where that name came from, and the contact that tells two same-named people apart"},"scheduledDate":{"type":["string","null"],"format":"date-time"},"dueDate":{"type":["string","null"],"format":"date-time"},"completedAt":{"type":["string","null"],"format":"date-time"},"completionNotes":{"type":["string","null"]},"estimatedCost":{"type":["number","null"],"minimum":0,"maximum":9999999999.99},"actualCost":{"type":["number","null"],"minimum":0,"maximum":9999999999.99},"createdAt":{"type":"string","format":"date-time"},"defectId":{"type":["string","null"],"format":"uuid","description":"The defect this service repairs (set on a DEFECT_REPAIR service). Null when there is none."},"assignedToUserId":{"type":["string","null"],"format":"uuid"},"assignedToCompany":{"type":["string","null"]},"performedByCompany":{"type":["string","null"]},"checklistTemplateId":{"type":["string","null"],"format":"uuid"},"hoursAtService":{"type":["integer","null"]},"kmAtService":{"type":["integer","null"]},"nextServiceHours":{"type":["integer","null"]},"nextServiceKm":{"type":["integer","null"]},"nextServiceDate":{"type":["string","null"],"format":"date-time"},"invoiceNumber":{"type":["string","null"]},"currency":{"type":["string","null"]},"completedByUserId":{"type":["string","null"],"format":"uuid"},"completedBy":{"type":["object","null"],"properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"A person: the name this org shows for them, where that name came from, and the contact that tells two same-named people apart"},"checklistTemplate":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"sectionTitle":{"type":["string","null"],"description":"The section the item sits in; null if none"},"text":{"type":"string"},"description":{"type":["string","null"]},"type":{"type":"string","enum":["PASS_FAIL","TEXT","NUMBER","SELECT","MULTI_SELECT","DATE","TIME","PHOTO","SIGNATURE","INSTRUCTION"]},"isRequired":{"type":"boolean","description":"Completing the service needs an answer to this item"},"isCritical":{"type":"boolean"},"options":{"type":["array","null"],"items":{"type":"string"},"description":"The choices of a SELECT or MULTI_SELECT item"},"failOn":{"type":["array","null"],"items":{"type":"string"},"description":"The SELECT or MULTI_SELECT choices that mean FAIL"},"min":{"type":["number","null"],"description":"Lowest passing reading of a NUMBER item"},"max":{"type":["number","null"],"description":"Highest passing reading of a NUMBER item"}},"required":["id","sectionTitle","text","description","type","isRequired","isCritical","options","failOn","min","max"],"description":"Service checklist item"},"description":"The checklist's current items, in section and display order"}},"required":["id","name","items"],"description":"The SERVICE checklist this service is completed against, with its items. Null when the service has none. Always sent."},"checklistResponses":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"checklistItemId":{"type":"string","format":"uuid"},"itemText":{"type":"string"},"itemType":{"type":"string","enum":["PASS_FAIL","TEXT","NUMBER","SELECT","MULTI_SELECT","DATE","TIME","PHOTO","SIGNATURE","INSTRUCTION"]},"response":{"type":"string","enum":["PASS","FAIL","NA"]},"value":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"The typed answer; null for PASS_FAIL"},"notes":{"type":["string","null"],"description":"Null when none"},"photoUrls":{"type":["array","null"],"items":{"type":"string"},"description":"Null when none"},"answeredAt":{"type":"string","format":"date-time","description":"When the answer was last recorded"}},"required":["id","checklistItemId","itemText","itemType","response","value","notes","photoUrls","answeredAt"],"description":"Service checklist answer"},"description":"The recorded checklist answers, in item order. Empty until the service is completed with its checklist; a service completed on the mobile app before it could run the checklist has none. Always sent."},"transitions":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"fromStatus":{"type":"string","enum":["UPCOMING","IN_PROGRESS","COMPLETED","CANCELED"]},"toStatus":{"type":"string","enum":["UPCOMING","IN_PROGRESS","COMPLETED","CANCELED"]},"userId":{"type":"string","format":"uuid"},"userName":{"type":["string","null"]},"user":{"type":["object","null"],"properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"A person: the name this org shows for them, where that name came from, and the contact that tells two same-named people apart"},"userMasked":{"type":"boolean"},"notes":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"}},"required":["id","fromStatus","toStatus","userId","userName","user","userMasked","notes","createdAt"],"description":"Service status transition"}}},"required":["id","equipmentId","equipmentName","trigger","serviceType","priority","status","title","description","assignedToName","assignedTo","performedByName","performedBy","scheduledDate","dueDate","completedAt","completionNotes","estimatedCost","actualCost","createdAt","assignedToUserId","assignedToCompany","performedByCompany","checklistTemplateId","hoursAtService","kmAtService","nextServiceHours","nextServiceKm","nextServiceDate","invoiceNumber","currency","completedByUserId","completedBy","transitions"],"description":"Service detail response"}},"required":["success","data"],"description":"Standard API success response"}}}},"404":{"description":"Service not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}},"patch":{"operationId":"updateService","summary":"Update service","description":"Updates service details such as description, scheduled date, or assigned technician.","tags":["Services"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"priority":{"type":"string","enum":["LOW","MEDIUM","HIGH","URGENT"]},"title":{"type":"string","minLength":1,"maxLength":255},"description":{"type":"string","maxLength":2000},"assignedToUserId":{"type":["string","null"],"format":"uuid"},"assignedToName":{"type":["string","null"],"minLength":1,"maxLength":255},"assignedToCompany":{"type":["string","null"],"minLength":1,"maxLength":255},"scheduledDate":{"type":["string","null"],"format":"date-time"},"dueDate":{"type":["string","null"],"format":"date-time"},"estimatedCost":{"type":["number","null"],"minimum":0,"maximum":9999999999.99},"actualCost":{"type":["number","null"],"minimum":0,"maximum":9999999999.99},"currency":{"type":"string"},"completionNotes":{"type":["string","null"],"maxLength":2000},"hoursAtService":{"type":["integer","null"],"minimum":0},"kmAtService":{"type":["integer","null"],"minimum":0},"checklistTemplateId":{"type":["string","null"],"format":"uuid","description":"The SERVICE checklist to complete this service against (an active SERVICE template of your organization), or null for none. Cannot change once checklist answers are recorded."},"completedAt":{"type":["string","null"],"format":"date-time"},"performedByName":{"type":["string","null"],"minLength":1,"maxLength":255},"performedByCompany":{"type":["string","null"],"minLength":1,"maxLength":255},"invoiceNumber":{"type":["string","null"],"maxLength":100},"nextServiceHours":{"type":["integer","null"],"minimum":0},"nextServiceKm":{"type":["integer","null"],"minimum":0},"nextServiceDate":{"type":["string","null"],"format":"date-time"}},"additionalProperties":false,"description":"Update a service"}}}},"responses":{"200":{"description":"Service updated","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"equipmentId":{"type":"string","format":"uuid"},"equipmentName":{"type":["string","null"]},"trigger":{"type":"string","enum":["PREDICTIVE","AD_HOC","DEFECT_REPAIR"]},"serviceType":{"type":"string","enum":["ROUTINE","REPAIR","INSPECTION","MODIFICATION","CERTIFICATION","OTHER"]},"priority":{"type":"string","enum":["LOW","MEDIUM","HIGH","URGENT"]},"status":{"type":"string","enum":["UPCOMING","IN_PROGRESS","COMPLETED","CANCELED"]},"title":{"type":["string","null"]},"description":{"type":["string","null"]},"assignedToName":{"type":["string","null"]},"assignedTo":{"type":["object","null"],"properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"A person: the name this org shows for them, where that name came from, and the contact that tells two same-named people apart"},"performedByName":{"type":["string","null"]},"performedBy":{"type":["object","null"],"properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"A person: the name this org shows for them, where that name came from, and the contact that tells two same-named people apart"},"scheduledDate":{"type":["string","null"],"format":"date-time"},"dueDate":{"type":["string","null"],"format":"date-time"},"completedAt":{"type":["string","null"],"format":"date-time"},"completionNotes":{"type":["string","null"]},"estimatedCost":{"type":["number","null"],"minimum":0,"maximum":9999999999.99},"actualCost":{"type":["number","null"],"minimum":0,"maximum":9999999999.99},"createdAt":{"type":"string","format":"date-time"},"defectId":{"type":["string","null"],"format":"uuid","description":"The defect this service repairs (set on a DEFECT_REPAIR service). Null when there is none."}},"required":["id","equipmentId","equipmentName","trigger","serviceType","priority","status","title","description","assignedToName","assignedTo","performedByName","performedBy","scheduledDate","dueDate","completedAt","completionNotes","estimatedCost","actualCost","createdAt"],"description":"Service list item response"}},"required":["success","data"],"description":"Standard API success response"}}}},"404":{"description":"Service not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}},"delete":{"operationId":"deleteService","summary":"Delete service (soft-delete)","description":"Soft-deletes a service. The record is retained for audit purposes but excluded from active lists.","tags":["Services"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"responses":{"204":{"description":"Service deleted"},"404":{"description":"Service not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}}},"/api/v1/services/:id/transition":{"post":{"operationId":"transitionService","summary":"Transition service status","description":"Advances a service to a new status in the workflow. Each transition is recorded in the audit trail.","tags":["Services"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"toStatus":{"type":"string","enum":["UPCOMING","IN_PROGRESS","COMPLETED","CANCELED"]},"notes":{"type":"string","maxLength":2000}},"required":["toStatus"],"additionalProperties":false,"description":"Transition a service status"}}}},"responses":{"200":{"description":"Service transitioned","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"equipmentId":{"type":"string","format":"uuid"},"equipmentName":{"type":["string","null"]},"trigger":{"type":"string","enum":["PREDICTIVE","AD_HOC","DEFECT_REPAIR"]},"serviceType":{"type":"string","enum":["ROUTINE","REPAIR","INSPECTION","MODIFICATION","CERTIFICATION","OTHER"]},"priority":{"type":"string","enum":["LOW","MEDIUM","HIGH","URGENT"]},"status":{"type":"string","enum":["UPCOMING","IN_PROGRESS","COMPLETED","CANCELED"]},"title":{"type":["string","null"]},"description":{"type":["string","null"]},"assignedToName":{"type":["string","null"]},"assignedTo":{"type":["object","null"],"properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"A person: the name this org shows for them, where that name came from, and the contact that tells two same-named people apart"},"performedByName":{"type":["string","null"]},"performedBy":{"type":["object","null"],"properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"A person: the name this org shows for them, where that name came from, and the contact that tells two same-named people apart"},"scheduledDate":{"type":["string","null"],"format":"date-time"},"dueDate":{"type":["string","null"],"format":"date-time"},"completedAt":{"type":["string","null"],"format":"date-time"},"completionNotes":{"type":["string","null"]},"estimatedCost":{"type":["number","null"],"minimum":0,"maximum":9999999999.99},"actualCost":{"type":["number","null"],"minimum":0,"maximum":9999999999.99},"createdAt":{"type":"string","format":"date-time"},"defectId":{"type":["string","null"],"format":"uuid","description":"The defect this service repairs (set on a DEFECT_REPAIR service). Null when there is none."}},"required":["id","equipmentId","equipmentName","trigger","serviceType","priority","status","title","description","assignedToName","assignedTo","performedByName","performedBy","scheduledDate","dueDate","completedAt","completionNotes","estimatedCost","actualCost","createdAt"],"description":"Service list item response"}},"required":["success","data"],"description":"Standard API success response"}}}},"404":{"description":"Service not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}}},"/api/v1/services/:id/complete":{"post":{"operationId":"completeService","summary":"Complete service","description":"Marks a service as completed with final notes and resets associated service alert counters. A service with a checklist (`checklistTemplateId`) needs its answers in `checklistResponses`, one per item, covering every required item; they are saved with the completion.","tags":["Services"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"completionNotes":{"type":"string","maxLength":2000},"hoursAtService":{"type":"integer","minimum":0},"kmAtService":{"type":"integer","minimum":0},"actualCost":{"type":"number","minimum":0,"maximum":9999999999.99},"checklistResponses":{"type":"array","items":{"type":"object","properties":{"checklistItemId":{"type":"string","format":"uuid","description":"An item of the service checklist"},"response":{"type":"string","enum":["PASS","FAIL","NA"],"description":"PASS, FAIL or NA for this item"},"value":{"anyOf":[{"type":"string","maxLength":2000},{"type":"number"},{"type":"boolean"},{"type":"array","items":{"type":"string","maxLength":2048},"maxItems":20},{"type":"null"}],"description":"The typed answer for a NUMBER, TEXT, SELECT, MULTI_SELECT, DATE, TIME, PHOTO or SIGNATURE item; omit it for PASS_FAIL"},"notes":{"type":"string","maxLength":1000,"description":"Free-text note on this answer"},"photoUrls":{"type":"array","items":{"type":"string","maxLength":2048,"format":"uri"},"maxItems":10,"description":"Uploaded photos attached to this answer (your organization's storage URLs)"}},"required":["checklistItemId","response"],"additionalProperties":false,"description":"One answer to a service checklist item"},"maxItems":500,"description":"Answers to the service's checklist, one per item. Required when the service has a checklist (`checklistTemplateId`): every required item must be answered (422 `service.checklist_incomplete` lists the missing ones), and each item must belong to that checklist. Refused when the service has no checklist."}},"additionalProperties":false,"description":"Complete a service with results"}}}},"responses":{"200":{"description":"Service completed","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"equipmentId":{"type":"string","format":"uuid"},"equipmentName":{"type":["string","null"]},"trigger":{"type":"string","enum":["PREDICTIVE","AD_HOC","DEFECT_REPAIR"]},"serviceType":{"type":"string","enum":["ROUTINE","REPAIR","INSPECTION","MODIFICATION","CERTIFICATION","OTHER"]},"priority":{"type":"string","enum":["LOW","MEDIUM","HIGH","URGENT"]},"status":{"type":"string","enum":["UPCOMING","IN_PROGRESS","COMPLETED","CANCELED"]},"title":{"type":["string","null"]},"description":{"type":["string","null"]},"assignedToName":{"type":["string","null"]},"assignedTo":{"type":["object","null"],"properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"A person: the name this org shows for them, where that name came from, and the contact that tells two same-named people apart"},"performedByName":{"type":["string","null"]},"performedBy":{"type":["object","null"],"properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"A person: the name this org shows for them, where that name came from, and the contact that tells two same-named people apart"},"scheduledDate":{"type":["string","null"],"format":"date-time"},"dueDate":{"type":["string","null"],"format":"date-time"},"completedAt":{"type":["string","null"],"format":"date-time"},"completionNotes":{"type":["string","null"]},"estimatedCost":{"type":["number","null"],"minimum":0,"maximum":9999999999.99},"actualCost":{"type":["number","null"],"minimum":0,"maximum":9999999999.99},"createdAt":{"type":"string","format":"date-time"},"defectId":{"type":["string","null"],"format":"uuid","description":"The defect this service repairs (set on a DEFECT_REPAIR service). Null when there is none."}},"required":["id","equipmentId","equipmentName","trigger","serviceType","priority","status","title","description","assignedToName","assignedTo","performedByName","performedBy","scheduledDate","dueDate","completedAt","completionNotes","estimatedCost","actualCost","createdAt"],"description":"Service list item response"}},"required":["success","data"],"description":"Standard API success response"}}}},"404":{"description":"Service not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}},"422":{"description":"Checklist answers refused: a required item is unanswered (`service.checklist_incomplete`, with `missingItemIds`), an answer is for an item outside the checklist (`service.checklist_item_not_in_checklist`) or repeats one (`service.checklist_duplicate_answer`), or the service has no checklist (`service.no_checklist`)","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}}},"/api/v1/services/:id/document":{"get":{"operationId":"getServiceDocument","summary":"Download service document (PDF)","description":"Generates a branded PDF for a single service — header details, the service checklist answers, and the full status-transition timeline.","tags":["Services"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"PDF document","content":{"application/pdf":{"schema":{"type":"string"}}}},"404":{"description":"Service not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}}},"/api/v1/services/:id/document/email":{"post":{"operationId":"emailServiceDocument","summary":"Email service document (PDF)","description":"Generates the service document PDF and emails it as an attachment to the given recipients.","tags":["Services"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"recipients":{"type":"array","items":{"type":"string"},"minItems":1,"maxItems":50}},"required":["recipients"],"additionalProperties":false,"description":"Email a service document PDF to the given recipients"}}}},"responses":{"200":{"description":"Document emailed","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"message":{"type":"string"}},"required":["success"],"description":"Action success response"}}}},"404":{"description":"Service not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}}},"/api/v1/webhooks":{"get":{"operationId":"listWebhooks","summary":"List webhooks","description":"Returns a cursor-paginated list of webhook configurations for the authenticated org.","tags":["Webhooks"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","maxLength":500},"required":false,"name":"after","in":"query"},{"schema":{"type":"string","maxLength":100},"required":false,"name":"search","in":"query"},{"schema":{"type":"boolean"},"required":false,"name":"isActive","in":"query"},{"schema":{"type":"boolean","description":"When true, only webhooks with at least one permanently failed delivery since their last successful one (failureCount greater than 0, the figure the Failures column shows). A successful delivery resets the count. false or omitted applies no failure filter."},"required":false,"description":"When true, only webhooks with at least one permanently failed delivery since their last successful one (failureCount greater than 0, the figure the Failures column shows). A successful delivery resets the count. false or omitted applies no failure filter.","name":"failing","in":"query"}],"responses":{"200":{"description":"List of webhooks","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"url":{"type":"string","maxLength":2048,"format":"uri"},"events":{"type":"array","items":{"type":"string","enum":["check.completed","defect.reported","service.completed"]}},"isActive":{"type":"boolean"},"description":{"type":["string","null"]},"lastDeliveredAt":{"type":["string","null"],"format":"date-time"},"failureCount":{"type":"integer"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","url","events","isActive","description","lastDeliveredAt","failureCount","createdAt"],"description":"Webhook list item response"}},"meta":{"type":"object","properties":{"limit":{"type":"number"},"hasMore":{"type":"boolean"},"nextCursor":{"type":["string","null"]},"server_time":{"type":"integer"}},"required":["limit","hasMore","nextCursor"]}},"required":["success","data","meta"],"description":"Cursor-paginated API success response"}}}}}},"post":{"operationId":"createWebhook","summary":"Create webhook","description":"Registers a new webhook endpoint. The signing secret is returned once in the response and cannot be retrieved again.","tags":["Webhooks"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","maxLength":2048,"format":"uri"},"events":{"type":"array","items":{"anyOf":[{"type":"string","enum":["check.completed","defect.reported","service.completed"]},{"type":"string","enum":["*"]}]},"minItems":1,"maxItems":50},"description":{"type":"string","maxLength":500}},"required":["url","events"],"additionalProperties":false,"description":"Create a new webhook subscription","example":{"url":"https://hooks.example.com/psg-events","events":["check.completed","defect.reported","service.completed"],"description":"Forward compliance events to our internal CMMS"}}}}},"responses":{"201":{"description":"Webhook created (secret returned once)","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"url":{"type":"string","maxLength":2048,"format":"uri"},"events":{"type":"array","items":{"type":"string","enum":["check.completed","defect.reported","service.completed"]}},"isActive":{"type":"boolean"},"description":{"type":["string","null"]},"lastDeliveredAt":{"type":["string","null"],"format":"date-time"},"failureCount":{"type":"integer"},"createdAt":{"type":"string","format":"date-time"},"secret":{"type":"string","minLength":32,"maxLength":256}},"required":["id","url","events","isActive","description","lastDeliveredAt","failureCount","createdAt","secret"],"description":"Webhook creation response — includes one-time plaintext secret"}},"required":["success","data"],"description":"Standard API success response"}}}}}}},"/api/v1/webhooks/:id":{"get":{"operationId":"getWebhook","summary":"Get webhook detail","description":"Retrieves the full configuration for a single webhook including its URL, events, and status.","tags":["Webhooks"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Webhook detail","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"url":{"type":"string","maxLength":2048,"format":"uri"},"events":{"type":"array","items":{"type":"string","enum":["check.completed","defect.reported","service.completed"]}},"isActive":{"type":"boolean"},"description":{"type":["string","null"]},"lastDeliveredAt":{"type":["string","null"],"format":"date-time"},"failureCount":{"type":"integer"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","url","events","isActive","description","lastDeliveredAt","failureCount","createdAt"],"description":"Webhook list item response"}},"required":["success","data"],"description":"Standard API success response"}}}},"404":{"description":"Webhook not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}},"patch":{"operationId":"updateWebhook","summary":"Update webhook","description":"Updates an existing webhook configuration such as URL, subscribed events, or enabled status.","tags":["Webhooks"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","maxLength":2048,"format":"uri"},"events":{"type":"array","items":{"anyOf":[{"type":"string","enum":["check.completed","defect.reported","service.completed"]},{"type":"string","enum":["*"]}]},"minItems":1,"maxItems":50},"isActive":{"type":"boolean"},"description":{"type":"string","maxLength":500}},"additionalProperties":false,"description":"Update webhook subscription"}}}},"responses":{"200":{"description":"Webhook updated","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"url":{"type":"string","maxLength":2048,"format":"uri"},"events":{"type":"array","items":{"type":"string","enum":["check.completed","defect.reported","service.completed"]}},"isActive":{"type":"boolean"},"description":{"type":["string","null"]},"lastDeliveredAt":{"type":["string","null"],"format":"date-time"},"failureCount":{"type":"integer"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","url","events","isActive","description","lastDeliveredAt","failureCount","createdAt"],"description":"Webhook list item response"}},"required":["success","data"],"description":"Standard API success response"}}}},"404":{"description":"Webhook not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}},"delete":{"operationId":"deleteWebhook","summary":"Delete webhook (soft-delete)","description":"Soft-deletes a webhook. It will no longer receive event deliveries.","tags":["Webhooks"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"responses":{"204":{"description":"Webhook deleted"},"404":{"description":"Webhook not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}}},"/api/v1/webhooks/:id/deliveries":{"get":{"operationId":"listWebhookDeliveries","summary":"List webhook deliveries","description":"Returns a cursor-paginated list of delivery attempts for a specific webhook, including HTTP status codes and response times.","tags":["Webhooks"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","maxLength":500},"required":false,"name":"after","in":"query"},{"schema":{"type":"string"},"required":false,"name":"eventType","in":"query"}],"responses":{"200":{"description":"List of webhook deliveries","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"webhookId":{"type":"string","format":"uuid"},"event":{"type":"string"},"eventType":{"type":"string"},"status":{"type":"string"},"statusCode":{"type":["integer","null"]},"attempt":{"type":"integer"},"requestBody":{"type":["string","null"]},"responseBody":{"type":["string","null"]},"duration":{"type":["integer","null"]},"deliveredAt":{"type":["string","null"],"format":"date-time"},"failedAt":{"type":["string","null"],"format":"date-time"},"errorMessage":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"}},"required":["id","webhookId","event","eventType","status","statusCode","attempt","requestBody","responseBody","duration","deliveredAt","failedAt","errorMessage","createdAt"],"description":"Webhook delivery response"}},"meta":{"type":"object","properties":{"limit":{"type":"number"},"hasMore":{"type":"boolean"},"nextCursor":{"type":["string","null"]},"server_time":{"type":"integer"}},"required":["limit","hasMore","nextCursor"]}},"required":["success","data","meta"],"description":"Cursor-paginated API success response"}}}},"404":{"description":"Webhook not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}}},"/api/v1/webhooks/:id/test":{"post":{"operationId":"testWebhook","summary":"Send test webhook delivery","description":"Sends a test payload to the webhook URL and returns the HTTP status code and response time.","tags":["Webhooks"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"responses":{"200":{"description":"Test delivery result","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"statusCode":{"type":"number"},"duration":{"type":"number"}},"required":["statusCode","duration"],"description":"Webhook test delivery result"}},"required":["success","data"],"description":"Standard API success response"}}}},"404":{"description":"Webhook not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}}},"/api/v1/webhooks/:id/rotate-secret":{"post":{"operationId":"rotateWebhookSecret","summary":"Rotate webhook signing secret","description":"Replaces the signing secret with a new one, returned once in the response and never again. The old secret stops working immediately: every delivery from then on, including retries of earlier events, is signed with the new secret, so update your endpoint straight away.","tags":["Webhooks"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"responses":{"200":{"description":"Secret rotated (new secret returned once)","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"url":{"type":"string","maxLength":2048,"format":"uri"},"events":{"type":"array","items":{"type":"string","enum":["check.completed","defect.reported","service.completed"]}},"isActive":{"type":"boolean"},"description":{"type":["string","null"]},"lastDeliveredAt":{"type":["string","null"],"format":"date-time"},"failureCount":{"type":"integer"},"createdAt":{"type":"string","format":"date-time"},"secret":{"type":"string","minLength":32,"maxLength":256,"description":"The new signing secret, shown once. Every delivery from now on, retries included, is signed with it."}},"required":["id","url","events","isActive","description","lastDeliveredAt","failureCount","createdAt","secret"],"description":"Webhook secret rotation response — includes the new one-time plaintext secret"}},"required":["success","data"],"description":"Standard API success response"}}}},"404":{"description":"Webhook not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}}},"/api/v1/documents":{"get":{"operationId":"listDocuments","summary":"List documents","description":"Returns a paginated list of documents attached to equipment, such as manuals, certificates, and service records.","tags":["Documents"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","maxLength":500},"required":false,"name":"after","in":"query"},{"schema":{"type":"string","enum":["MANUAL","RISK_ASSESSMENT","SWMS","CERTIFICATE","REGISTRATION","INSURANCE","WARRANTY","SERVICE_REPORT","OTHER"]},"required":false,"name":"documentType","in":"query"},{"schema":{"type":"string","format":"uuid"},"required":false,"name":"equipmentId","in":"query"},{"schema":{"type":"string","format":"uuid"},"required":false,"name":"siteId","in":"query"},{"schema":{"type":"string","maxLength":100},"required":false,"name":"search","in":"query"},{"schema":{"type":"boolean"},"required":false,"name":"expired","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":365,"description":"Return only documents whose expiry date falls after now and no later than this many days from now (1 to 365). A document with no expiry date, or one that has already expired, is not included; use expired=true for the expired ones."},"required":false,"description":"Return only documents whose expiry date falls after now and no later than this many days from now (1 to 365). A document with no expiry date, or one that has already expired, is not included; use expired=true for the expired ones.","name":"expiringWithinDays","in":"query"}],"responses":{"200":{"description":"The list of documents","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"documentType":{"type":"string","enum":["MANUAL","RISK_ASSESSMENT","SWMS","CERTIFICATE","REGISTRATION","INSURANCE","WARRANTY","SERVICE_REPORT","OTHER"]},"visibility":{"type":"string","enum":["INTERNAL","OWNER_ONLY","PUBLIC"],"description":"A5 — document classification for the public digital logbook: INTERNAL keeps metadata visible but no download URL, OWNER_ONLY is reserved for the future authenticated view, PUBLIC mints a 15-minute signed GCS URL."},"name":{"type":"string"},"description":{"type":["string","null"]},"fileUrl":{"type":"string","maxLength":2048,"format":"uri"},"fileName":{"type":["string","null"],"maxLength":255},"fileSize":{"type":["integer","null"],"minimum":0},"mimeType":{"type":["string","null"],"maxLength":100},"version":{"type":["string","null"]},"revisionNumber":{"type":["integer","null"],"exclusiveMinimum":0},"revisionCount":{"type":"integer","minimum":0},"issuedAt":{"type":["string","null"],"format":"date-time"},"expiresAt":{"type":["string","null"],"format":"date-time"},"requiresAcknowledgment":{"type":"boolean"},"acknowledged":{"type":"boolean"},"equipmentId":{"type":["string","null"],"format":"uuid"},"equipmentName":{"type":["string","null"]},"uploadedByUserName":{"type":["string","null"]},"uploadedByUser":{"type":["object","null"],"properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"A person: the name this org shows for them, where that name came from, and the contact that tells two same-named people apart"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","documentType","visibility","name","description","fileUrl","fileName","fileSize","mimeType","version","revisionNumber","revisionCount","issuedAt","expiresAt","requiresAcknowledgment","acknowledged","equipmentId","equipmentName","uploadedByUserName","uploadedByUser","createdAt"],"description":"Document response"}},"meta":{"type":"object","properties":{"limit":{"type":"number"},"hasMore":{"type":"boolean"},"nextCursor":{"type":["string","null"]},"server_time":{"type":"integer"}},"required":["limit","hasMore","nextCursor"]}},"required":["success","data","meta"],"description":"Cursor-paginated API success response"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}},"post":{"operationId":"createDocument","summary":"Create a document","description":"Creates a new document record linked to an asset. Only the owner org can manage asset documents.","tags":["Documents"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"equipmentId":{"type":"string","format":"uuid"},"documentType":{"type":"string","enum":["MANUAL","RISK_ASSESSMENT","SWMS","CERTIFICATE","REGISTRATION","INSURANCE","WARRANTY","SERVICE_REPORT","OTHER"]},"name":{"type":"string","minLength":1,"maxLength":255},"description":{"type":"string","maxLength":2000},"fileUrl":{"type":"string","maxLength":2048,"format":"uri"},"fileSize":{"type":"integer","minimum":0},"mimeType":{"type":"string","maxLength":100},"version":{"type":"string","minLength":1,"maxLength":50},"issuedAt":{"type":"string","format":"date-time"},"expiresAt":{"type":"string","format":"date-time"},"requiresAcknowledgment":{"type":"boolean"},"visibility":{"type":"string","enum":["INTERNAL","OWNER_ONLY","PUBLIC"],"description":"A5 — document classification for the public digital logbook: INTERNAL keeps metadata visible but no download URL, OWNER_ONLY is reserved for the future authenticated view, PUBLIC mints a 15-minute signed GCS URL."}},"required":["documentType","name","fileUrl"],"additionalProperties":false,"description":"Upload a new document"}}}},"responses":{"201":{"description":"The created document","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"documentType":{"type":"string","enum":["MANUAL","RISK_ASSESSMENT","SWMS","CERTIFICATE","REGISTRATION","INSURANCE","WARRANTY","SERVICE_REPORT","OTHER"]},"visibility":{"type":"string","enum":["INTERNAL","OWNER_ONLY","PUBLIC"],"description":"A5 — document classification for the public digital logbook: INTERNAL keeps metadata visible but no download URL, OWNER_ONLY is reserved for the future authenticated view, PUBLIC mints a 15-minute signed GCS URL."},"name":{"type":"string"},"description":{"type":["string","null"]},"fileUrl":{"type":"string","maxLength":2048,"format":"uri"},"fileName":{"type":["string","null"],"maxLength":255},"fileSize":{"type":["integer","null"],"minimum":0},"mimeType":{"type":["string","null"],"maxLength":100},"version":{"type":["string","null"]},"revisionNumber":{"type":["integer","null"],"exclusiveMinimum":0},"revisionCount":{"type":"integer","minimum":0},"issuedAt":{"type":["string","null"],"format":"date-time"},"expiresAt":{"type":["string","null"],"format":"date-time"},"requiresAcknowledgment":{"type":"boolean"},"acknowledged":{"type":"boolean"},"equipmentId":{"type":["string","null"],"format":"uuid"},"equipmentName":{"type":["string","null"]},"uploadedByUserName":{"type":["string","null"]},"uploadedByUser":{"type":["object","null"],"properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"A person: the name this org shows for them, where that name came from, and the contact that tells two same-named people apart"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","documentType","visibility","name","description","fileUrl","fileName","fileSize","mimeType","version","revisionNumber","revisionCount","issuedAt","expiresAt","requiresAcknowledgment","acknowledged","equipmentId","equipmentName","uploadedByUserName","uploadedByUser","createdAt"],"description":"Document response"}},"required":["success","data"],"description":"Standard API success response"}}}},"400":{"description":"Invalid input","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}}},"/api/v1/documents/:id":{"get":{"operationId":"getDocument","summary":"Get a document by ID","description":"Retrieves the metadata and download URL for a single document.","tags":["Documents"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The document details","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"documentType":{"type":"string","enum":["MANUAL","RISK_ASSESSMENT","SWMS","CERTIFICATE","REGISTRATION","INSURANCE","WARRANTY","SERVICE_REPORT","OTHER"]},"visibility":{"type":"string","enum":["INTERNAL","OWNER_ONLY","PUBLIC"],"description":"A5 — document classification for the public digital logbook: INTERNAL keeps metadata visible but no download URL, OWNER_ONLY is reserved for the future authenticated view, PUBLIC mints a 15-minute signed GCS URL."},"name":{"type":"string"},"description":{"type":["string","null"]},"fileUrl":{"type":"string","maxLength":2048,"format":"uri"},"fileName":{"type":["string","null"],"maxLength":255},"fileSize":{"type":["integer","null"],"minimum":0},"mimeType":{"type":["string","null"],"maxLength":100},"version":{"type":["string","null"]},"revisionNumber":{"type":["integer","null"],"exclusiveMinimum":0},"revisionCount":{"type":"integer","minimum":0},"issuedAt":{"type":["string","null"],"format":"date-time"},"expiresAt":{"type":["string","null"],"format":"date-time"},"requiresAcknowledgment":{"type":"boolean"},"acknowledged":{"type":"boolean"},"equipmentId":{"type":["string","null"],"format":"uuid"},"equipmentName":{"type":["string","null"]},"uploadedByUserName":{"type":["string","null"]},"uploadedByUser":{"type":["object","null"],"properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"A person: the name this org shows for them, where that name came from, and the contact that tells two same-named people apart"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","documentType","visibility","name","description","fileUrl","fileName","fileSize","mimeType","version","revisionNumber","revisionCount","issuedAt","expiresAt","requiresAcknowledgment","acknowledged","equipmentId","equipmentName","uploadedByUserName","uploadedByUser","createdAt"],"description":"Document response"}},"required":["success","data"],"description":"Standard API success response"}}}},"404":{"description":"Document not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}},"patch":{"operationId":"updateDocument","summary":"Update a document","description":"Updates metadata for an existing document. Only the owner org can manage asset documents.","tags":["Documents"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":255},"description":{"type":"string","maxLength":2000},"documentType":{"type":"string","enum":["MANUAL","RISK_ASSESSMENT","SWMS","CERTIFICATE","REGISTRATION","INSURANCE","WARRANTY","SERVICE_REPORT","OTHER"]},"equipmentId":{"type":["string","null"],"format":"uuid"},"expiresAt":{"type":["string","null"],"format":"date-time"},"issuedAt":{"type":["string","null"],"format":"date-time"},"requiresAcknowledgment":{"type":"boolean"},"visibility":{"type":"string","enum":["INTERNAL","OWNER_ONLY","PUBLIC"],"description":"A5 — document classification for the public digital logbook: INTERNAL keeps metadata visible but no download URL, OWNER_ONLY is reserved for the future authenticated view, PUBLIC mints a 15-minute signed GCS URL."}},"additionalProperties":false,"description":"Update an existing document"}}}},"responses":{"200":{"description":"The updated document","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"documentType":{"type":"string","enum":["MANUAL","RISK_ASSESSMENT","SWMS","CERTIFICATE","REGISTRATION","INSURANCE","WARRANTY","SERVICE_REPORT","OTHER"]},"visibility":{"type":"string","enum":["INTERNAL","OWNER_ONLY","PUBLIC"],"description":"A5 — document classification for the public digital logbook: INTERNAL keeps metadata visible but no download URL, OWNER_ONLY is reserved for the future authenticated view, PUBLIC mints a 15-minute signed GCS URL."},"name":{"type":"string"},"description":{"type":["string","null"]},"fileUrl":{"type":"string","maxLength":2048,"format":"uri"},"fileName":{"type":["string","null"],"maxLength":255},"fileSize":{"type":["integer","null"],"minimum":0},"mimeType":{"type":["string","null"],"maxLength":100},"version":{"type":["string","null"]},"revisionNumber":{"type":["integer","null"],"exclusiveMinimum":0},"revisionCount":{"type":"integer","minimum":0},"issuedAt":{"type":["string","null"],"format":"date-time"},"expiresAt":{"type":["string","null"],"format":"date-time"},"requiresAcknowledgment":{"type":"boolean"},"acknowledged":{"type":"boolean"},"equipmentId":{"type":["string","null"],"format":"uuid"},"equipmentName":{"type":["string","null"]},"uploadedByUserName":{"type":["string","null"]},"uploadedByUser":{"type":["object","null"],"properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"A person: the name this org shows for them, where that name came from, and the contact that tells two same-named people apart"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","documentType","visibility","name","description","fileUrl","fileName","fileSize","mimeType","version","revisionNumber","revisionCount","issuedAt","expiresAt","requiresAcknowledgment","acknowledged","equipmentId","equipmentName","uploadedByUserName","uploadedByUser","createdAt"],"description":"Document response"}},"required":["success","data"],"description":"Standard API success response"}}}},"404":{"description":"Document not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}},"delete":{"operationId":"deleteDocument","summary":"Delete a document","description":"Soft-deletes a document record. The underlying file is retained for audit compliance.","tags":["Documents"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"responses":{"204":{"description":"Document deleted"},"404":{"description":"Document not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}}},"/api/v1/documents/:id/revisions":{"post":{"operationId":"createDocumentRevision","summary":"Upload a new document revision","description":"Creates a new revision for an existing document. The document's file fields are updated to reflect the latest revision.","tags":["Documents"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"fileUrl":{"type":"string","maxLength":2048,"format":"uri"},"fileSize":{"type":"integer","minimum":0},"mimeType":{"type":"string","maxLength":100},"fileName":{"type":"string","maxLength":500},"changeNotes":{"type":"string","maxLength":2000}},"required":["fileUrl"],"additionalProperties":false,"description":"Upload a new document revision"}}}},"responses":{"201":{"description":"The created revision","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"revisionNumber":{"type":"integer","exclusiveMinimum":0},"fileUrl":{"type":"string","maxLength":2048,"format":"uri"},"fileSize":{"type":["integer","null"],"minimum":0},"mimeType":{"type":["string","null"],"maxLength":100},"fileName":{"type":["string","null"],"maxLength":255},"changeNotes":{"type":["string","null"]},"uploadedByUserName":{"type":["string","null"]},"uploadedByUser":{"type":["object","null"],"properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"A person: the name this org shows for them, where that name came from, and the contact that tells two same-named people apart"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","revisionNumber","fileUrl","fileSize","mimeType","fileName","changeNotes","uploadedByUserName","uploadedByUser","createdAt"],"description":"Document revision response"}},"required":["success","data"],"description":"Standard API success response"}}}},"404":{"description":"Document not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}},"get":{"operationId":"listDocumentRevisions","summary":"List document revisions","description":"Returns a paginated list of all revisions for a document, ordered by newest first.","tags":["Documents"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","maxLength":500},"required":false,"name":"after","in":"query"}],"responses":{"200":{"description":"The list of revisions","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"revisionNumber":{"type":"integer","exclusiveMinimum":0},"fileUrl":{"type":"string","maxLength":2048,"format":"uri"},"fileSize":{"type":["integer","null"],"minimum":0},"mimeType":{"type":["string","null"],"maxLength":100},"fileName":{"type":["string","null"],"maxLength":255},"changeNotes":{"type":["string","null"]},"uploadedByUserName":{"type":["string","null"]},"uploadedByUser":{"type":["object","null"],"properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"A person: the name this org shows for them, where that name came from, and the contact that tells two same-named people apart"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","revisionNumber","fileUrl","fileSize","mimeType","fileName","changeNotes","uploadedByUserName","uploadedByUser","createdAt"],"description":"Document revision response"}},"meta":{"type":"object","properties":{"limit":{"type":"number"},"hasMore":{"type":"boolean"},"nextCursor":{"type":["string","null"]},"server_time":{"type":"integer"}},"required":["limit","hasMore","nextCursor"]}},"required":["success","data","meta"],"description":"Cursor-paginated API success response"}}}},"404":{"description":"Document not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}}},"/api/v1/documents/:id/revisions/:revisionId":{"get":{"operationId":"getDocumentRevision","summary":"Get a specific revision","description":"Retrieves metadata and download URL for a specific document revision.","tags":["Documents"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"revisionId","in":"path"}],"responses":{"200":{"description":"The revision details","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"revisionNumber":{"type":"integer","exclusiveMinimum":0},"fileUrl":{"type":"string","maxLength":2048,"format":"uri"},"fileSize":{"type":["integer","null"],"minimum":0},"mimeType":{"type":["string","null"],"maxLength":100},"fileName":{"type":["string","null"],"maxLength":255},"changeNotes":{"type":["string","null"]},"uploadedByUserName":{"type":["string","null"]},"uploadedByUser":{"type":["object","null"],"properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"A person: the name this org shows for them, where that name came from, and the contact that tells two same-named people apart"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","revisionNumber","fileUrl","fileSize","mimeType","fileName","changeNotes","uploadedByUserName","uploadedByUser","createdAt"],"description":"Document revision response"}},"required":["success","data"],"description":"Standard API success response"}}}},"404":{"description":"Revision not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}}},"/api/v1/compliance/status":{"get":{"operationId":"getComplianceStatus","summary":"Get three-layer compliance status","description":"Returns the three-layer compliance status (license, site induction, pre-start check) for the requesting user or a specified user.","tags":["Compliance"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"siteId","in":"query"},{"schema":{"type":"string","format":"uuid"},"required":false,"name":"equipmentId","in":"query"},{"schema":{"type":"string","format":"uuid"},"required":false,"name":"userId","in":"query"}],"responses":{"200":{"description":"Compliance status for all layers","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"siteId":{"type":"string","format":"uuid"},"siteName":{"type":"string"},"equipmentId":{"type":["string","null"],"format":"uuid"},"equipmentName":{"type":["string","null"]},"userId":{"type":"string","format":"uuid"},"userName":{"type":"string"},"user":{"type":["object","null"],"properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"A person: the name this org shows for them, where that name came from, and the contact that tells two same-named people apart"},"allSatisfied":{"type":"boolean"},"layers":{"type":"array","items":{"type":"object","properties":{"layer":{"type":"string","enum":["PERSONNEL_INDUCTION","EQUIPMENT_INDUCTION","CHECK_IN","TOOLBOX","SPOTTER"]},"required":{"type":"boolean"},"satisfied":{"type":"boolean"},"overridden":{"type":"boolean"},"details":{"type":["string","null"]},"blockingReason":{"type":["string","null"]},"resolutionGuidance":{"type":["string","null"]},"contactName":{"type":["string","null"]},"contactPhone":{"type":["string","null"],"maxLength":20},"contact":{"type":["object","null"],"properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"A person: the name this org shows for them, where that name came from, and the contact that tells two same-named people apart"}},"required":["layer","required","satisfied","overridden","contact"],"description":"Status of a single compliance layer"}}},"required":["siteId","siteName","userId","userName","user","allSatisfied","layers"],"description":"Full three-layer compliance status"}},"required":["success","data"],"description":"Standard API success response"}}}},"401":{"description":"Unauthorized — missing or invalid token","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}},"403":{"description":"Forbidden — insufficient role","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}}},"/api/v1/compliance/overview":{"get":{"operationId":"getComplianceOverview","summary":"Get site compliance overview with aggregated stats","description":"Returns aggregated compliance statistics for a specific site, including check rates, override counts, and compliance scores.","tags":["Compliance"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"siteId","in":"query"}],"responses":{"200":{"description":"Site compliance overview","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"siteId":{"type":"string","format":"uuid"},"siteName":{"type":"string"},"totalUsers":{"type":"integer","description":"People on the site's live roster (active, in-window site access): the population every rate divides by"},"inductedCount":{"type":"integer","description":"People inducted at the site. Being on the live site roster is the induction, so this equals totalUsers"},"checkedInCount":{"type":"integer","description":"Roster members checked in at the site today (site timezone)"},"toolboxCount":{"type":"integer","description":"Roster members at a toolbox talk conducted at the site today (site timezone)"},"overrideCount":{"type":"integer"},"inductionRate":{"type":"number","minimum":0,"maximum":100},"checkInRate":{"type":"number","minimum":0,"maximum":100},"toolboxRate":{"type":"number","minimum":0,"maximum":100},"overallRate":{"type":["number","null"],"minimum":0,"maximum":100,"description":"Average of the rates of the layers this site requires; null when it requires none or nobody is on the roster. Changed 2026-10: this was always a number (0 for an empty roster) and averaged all three layers whether required or not, so treat null as \"not applicable\" rather than 0"},"inductionRequired":{"type":"boolean","description":"Whether the site requires personnel induction: the org's enforce switch AND the site's resolved workflow"},"checkInRequired":{"type":"boolean","description":"Whether the site requires check-in: the org's enforce switch AND the site's resolved workflow"},"toolboxRequired":{"type":"boolean","description":"Whether the site requires toolbox attendance: the siteCheckIn feature AND the org's enforce switch AND the site's resolved workflow"}},"required":["siteId","siteName","totalUsers","inductedCount","checkedInCount","toolboxCount","overrideCount","inductionRate","checkInRate","toolboxRate","overallRate"],"description":"Site-wide compliance overview"}},"required":["success","data"],"description":"Standard API success response"}}}},"400":{"description":"Invalid query parameters","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}},"401":{"description":"Unauthorized — missing or invalid token","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}},"403":{"description":"Forbidden — insufficient role","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}},"404":{"description":"Site not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}}},"/api/v1/compliance/operators":{"get":{"operationId":"getSiteOperatorsCompliance","summary":"Batch compliance status for site operators","description":"Returns compliance status for up to 100 users at a site in a single call. Accepts siteId + comma-joined userIds. Requires EDITOR role (admin view).","tags":["Compliance"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"siteId","in":"query"},{"schema":{"type":"string","minLength":1,"description":"Comma-separated list of user UUIDs (max 100)"},"required":true,"description":"Comma-separated list of user UUIDs (max 100)","name":"userIds","in":"query"}],"responses":{"200":{"description":"Compliance status array for all requested users","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"type":"object","properties":{"siteId":{"type":"string","format":"uuid"},"siteName":{"type":"string"},"equipmentId":{"type":["string","null"],"format":"uuid"},"equipmentName":{"type":["string","null"]},"userId":{"type":"string","format":"uuid"},"userName":{"type":"string"},"user":{"type":["object","null"],"properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"A person: the name this org shows for them, where that name came from, and the contact that tells two same-named people apart"},"allSatisfied":{"type":"boolean"},"layers":{"type":"array","items":{"type":"object","properties":{"layer":{"type":"string","enum":["PERSONNEL_INDUCTION","EQUIPMENT_INDUCTION","CHECK_IN","TOOLBOX","SPOTTER"]},"required":{"type":"boolean"},"satisfied":{"type":"boolean"},"overridden":{"type":"boolean"},"details":{"type":["string","null"]},"blockingReason":{"type":["string","null"]},"resolutionGuidance":{"type":["string","null"]},"contactName":{"type":["string","null"]},"contactPhone":{"type":["string","null"],"maxLength":20},"contact":{"type":["object","null"],"properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"A person: the name this org shows for them, where that name came from, and the contact that tells two same-named people apart"}},"required":["layer","required","satisfied","overridden","contact"],"description":"Status of a single compliance layer"}}},"required":["siteId","siteName","userId","userName","user","allSatisfied","layers"],"description":"Full three-layer compliance status"}}},"required":["success","data"],"description":"Standard API success response"}}}},"400":{"description":"Invalid query parameters","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}},"401":{"description":"Unauthorized — missing or invalid token","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}},"403":{"description":"Forbidden — insufficient role","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}},"404":{"description":"Site not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}}},"/api/v1/zones":{"get":{"operationId":"listAllZones","summary":"List all zones","description":"Returns a paginated list of all zones (purpose-typed geofences) across all sites for the org.","tags":["Zones"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","maxLength":500},"required":false,"name":"after","in":"query"},{"schema":{"type":"string","format":"uuid"},"required":false,"name":"siteId","in":"query"},{"schema":{"type":"string","enum":["EXCLUSION","RESTRICTED","SPEED_LIMIT","HAZARD"]},"required":false,"name":"purpose","in":"query"},{"schema":{"type":"boolean"},"required":false,"name":"isActive","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":255},"required":false,"name":"search","in":"query"}],"responses":{"200":{"description":"List of zones","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"description":{"type":["string","null"]},"type":{"type":"string","enum":["CIRCLE","POLYGON"]},"purpose":{"type":"string","enum":["GENERAL","EXCLUSION","RESTRICTED","SPEED_LIMIT","HAZARD"]},"isActive":{"type":"boolean"},"autoDisable":{"type":"boolean"},"alertOnEnter":{"type":"boolean"},"alertOnExit":{"type":"boolean"},"alertOnDwell":{"type":"boolean"},"dwellTimeMinutes":{"type":["integer","null"]},"siteId":{"type":["string","null"],"format":"uuid"},"siteName":{"type":["string","null"]},"latitude":{"type":["number","null"],"minimum":-90,"maximum":90,"description":"WGS-84 latitude in decimal degrees (-90 to 90)"},"longitude":{"type":["number","null"],"minimum":-180,"maximum":180,"description":"WGS-84 longitude in decimal degrees (-180 to 180)"},"radiusMeters":{"type":["number","null"]},"polygon":{"type":["array","null"],"items":{"type":"object","properties":{"lat":{"type":"number","minimum":-90,"maximum":90,"description":"WGS-84 latitude in decimal degrees (-90 to 90)"},"lng":{"type":"number","minimum":-180,"maximum":180,"description":"WGS-84 longitude in decimal degrees (-180 to 180)"}},"required":["lat","lng"],"description":"A single WGS-84 polygon vertex (lat/lng in decimal degrees)"}},"color":{"type":["string","null"]},"zoneConfig":{"type":["object","null"],"additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},"createdAt":{"type":"string","format":"date-time"}},"required":["id","name","description","type","purpose","isActive","autoDisable","alertOnEnter","alertOnExit","alertOnDwell","dwellTimeMinutes","siteId","siteName","latitude","longitude","radiusMeters","polygon","color","zoneConfig","createdAt"],"description":"Zone response (purpose-typed geofence)"}},"meta":{"type":"object","properties":{"limit":{"type":"number"},"hasMore":{"type":"boolean"},"nextCursor":{"type":["string","null"]},"server_time":{"type":"integer"}},"required":["limit","hasMore","nextCursor"]}},"required":["success","data","meta"],"description":"Cursor-paginated API success response"}}}}}}},"/api/v1/zones/:id":{"get":{"operationId":"getZoneById","summary":"Get zone details (org-scoped)","description":"Retrieves a single zone by ID within the org, without requiring its site ID. Backs the zone-detail page. Cross-org zones resolve as 404.","tags":["Zones"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Zone details","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"description":{"type":["string","null"]},"type":{"type":"string","enum":["CIRCLE","POLYGON"]},"purpose":{"type":"string","enum":["GENERAL","EXCLUSION","RESTRICTED","SPEED_LIMIT","HAZARD"]},"isActive":{"type":"boolean"},"autoDisable":{"type":"boolean"},"alertOnEnter":{"type":"boolean"},"alertOnExit":{"type":"boolean"},"alertOnDwell":{"type":"boolean"},"dwellTimeMinutes":{"type":["integer","null"]},"siteId":{"type":["string","null"],"format":"uuid"},"siteName":{"type":["string","null"]},"latitude":{"type":["number","null"],"minimum":-90,"maximum":90,"description":"WGS-84 latitude in decimal degrees (-90 to 90)"},"longitude":{"type":["number","null"],"minimum":-180,"maximum":180,"description":"WGS-84 longitude in decimal degrees (-180 to 180)"},"radiusMeters":{"type":["number","null"]},"polygon":{"type":["array","null"],"items":{"type":"object","properties":{"lat":{"type":"number","minimum":-90,"maximum":90,"description":"WGS-84 latitude in decimal degrees (-90 to 90)"},"lng":{"type":"number","minimum":-180,"maximum":180,"description":"WGS-84 longitude in decimal degrees (-180 to 180)"}},"required":["lat","lng"],"description":"A single WGS-84 polygon vertex (lat/lng in decimal degrees)"}},"color":{"type":["string","null"]},"zoneConfig":{"type":["object","null"],"additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},"createdAt":{"type":"string","format":"date-time"}},"required":["id","name","description","type","purpose","isActive","autoDisable","alertOnEnter","alertOnExit","alertOnDwell","dwellTimeMinutes","siteId","siteName","latitude","longitude","radiusMeters","polygon","color","zoneConfig","createdAt"],"description":"Zone response (purpose-typed geofence)"}},"required":["success","data"],"description":"Standard API success response"}}}},"404":{"description":"Zone not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}}},"/api/v1/observations":{"get":{"operationId":"listObservations","summary":"List observations","description":"Returns a paginated list of observations for the authenticated org. Supports filtering by site, status, severity, and type.","tags":["Observations"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","maxLength":500},"required":false,"name":"after","in":"query"},{"schema":{"type":"string","maxLength":100},"required":false,"name":"search","in":"query"},{"schema":{"type":"string","format":"uuid"},"required":false,"name":"siteId","in":"query"},{"schema":{"type":"string","enum":["REPORTED","REVIEWED","ACTIONED","CLOSED","DISMISSED"]},"required":false,"name":"status","in":"query"},{"schema":{"type":"string","enum":["LOW","MEDIUM","HIGH","CRITICAL"]},"required":false,"name":"severity","in":"query"},{"schema":{"type":"string","enum":["HAZARD","NEAR_MISS","UNSAFE_ACT","UNSAFE_CONDITION","POSITIVE","OTHER"]},"required":false,"name":"observationType","in":"query"},{"schema":{"type":"string","format":"uuid"},"required":false,"name":"assignedToUserId","in":"query"}],"responses":{"200":{"description":"List of observations","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"observationType":{"type":"string","enum":["HAZARD","NEAR_MISS","UNSAFE_ACT","UNSAFE_CONDITION","POSITIVE","OTHER"]},"title":{"type":"string"},"description":{"type":"string","maxLength":2000},"severity":{"type":"string","enum":["LOW","MEDIUM","HIGH","CRITICAL"]},"status":{"type":"string","enum":["REPORTED","REVIEWED","ACTIONED","CLOSED","DISMISSED"]},"raisedAt":{"type":"string","format":"date-time"},"raisedBy":{"type":"object","properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"User who raised the observation"},"site":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"}},"required":["id","name"],"description":"Site where the observation was raised"},"assignedTo":{"type":["object","null"],"properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"User assigned to the observation"},"photosCount":{"type":"integer"},"commentsCount":{"type":"integer"},"scanSource":{"type":["string","null"],"enum":["qr","nfc","serial",null],"description":"How the user reached the equipment-anchored action: QR scan, NFC tap, or manual serial entry."}},"required":["id","observationType","title","description","severity","status","raisedAt","raisedBy","site","assignedTo","photosCount","commentsCount"],"description":"Observation list item response"}},"meta":{"type":"object","properties":{"limit":{"type":"number"},"hasMore":{"type":"boolean"},"nextCursor":{"type":["string","null"]},"server_time":{"type":"integer"}},"required":["limit","hasMore","nextCursor"]}},"required":["success","data","meta"],"description":"Cursor-paginated API success response"}}}}}},"post":{"operationId":"createObservation","summary":"Create observation","description":"Reports a new observation at a site.","tags":["Observations"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"siteId":{"type":"string","format":"uuid"},"observationType":{"type":"string","enum":["HAZARD","NEAR_MISS","UNSAFE_ACT","UNSAFE_CONDITION","POSITIVE","OTHER"]},"title":{"type":"string","minLength":1,"maxLength":255},"description":{"type":"string","maxLength":2000},"severity":{"type":"string","enum":["LOW","MEDIUM","HIGH","CRITICAL"],"default":"MEDIUM"},"notes":{"type":"string","maxLength":2000},"raisedLatitude":{"type":["number","null"],"minimum":-90,"maximum":90,"description":"WGS-84 latitude in decimal degrees (-90 to 90)"},"raisedLongitude":{"type":["number","null"],"minimum":-180,"maximum":180,"description":"WGS-84 longitude in decimal degrees (-180 to 180)"},"scanSource":{"type":["string","null"],"enum":["qr","nfc","serial",null],"description":"How the user reached the equipment-anchored action: QR scan, NFC tap, or manual serial entry."},"localId":{"type":["string","null"],"maxLength":100}},"required":["siteId","observationType","title","description"],"additionalProperties":false,"description":"Report a new observation at a site"}}}},"responses":{"201":{"description":"Observation created","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"observationType":{"type":"string","enum":["HAZARD","NEAR_MISS","UNSAFE_ACT","UNSAFE_CONDITION","POSITIVE","OTHER"]},"title":{"type":"string"},"description":{"type":"string","maxLength":2000},"severity":{"type":"string","enum":["LOW","MEDIUM","HIGH","CRITICAL"]},"status":{"type":"string","enum":["REPORTED","REVIEWED","ACTIONED","CLOSED","DISMISSED"]},"raisedAt":{"type":"string","format":"date-time"},"raisedBy":{"type":"object","properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"User who raised the observation"},"site":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"}},"required":["id","name"],"description":"Site where the observation was raised"},"assignedTo":{"type":["object","null"],"properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"User assigned to the observation"},"photosCount":{"type":"integer"},"commentsCount":{"type":"integer"},"scanSource":{"type":["string","null"],"enum":["qr","nfc","serial",null],"description":"How the user reached the equipment-anchored action: QR scan, NFC tap, or manual serial entry."}},"required":["id","observationType","title","description","severity","status","raisedAt","raisedBy","site","assignedTo","photosCount","commentsCount"],"description":"Observation list item response"}},"required":["success","data"],"description":"Standard API success response"}}}}}}},"/api/v1/observations/:id":{"get":{"operationId":"getObservation","summary":"Get observation","description":"Returns full details of an observation.","tags":["Observations"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Observation details","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"observationType":{"type":"string","enum":["HAZARD","NEAR_MISS","UNSAFE_ACT","UNSAFE_CONDITION","POSITIVE","OTHER"]},"title":{"type":"string"},"description":{"type":"string","maxLength":2000},"severity":{"type":"string","enum":["LOW","MEDIUM","HIGH","CRITICAL"]},"status":{"type":"string","enum":["REPORTED","REVIEWED","ACTIONED","CLOSED","DISMISSED"]},"raisedAt":{"type":"string","format":"date-time"},"raisedBy":{"type":"object","properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"User who raised the observation"},"site":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"}},"required":["id","name"],"description":"Site where the observation was raised"},"assignedTo":{"type":["object","null"],"properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"User assigned to the observation"},"photosCount":{"type":"integer"},"commentsCount":{"type":"integer"},"scanSource":{"type":["string","null"],"enum":["qr","nfc","serial",null],"description":"How the user reached the equipment-anchored action: QR scan, NFC tap, or manual serial entry."},"notes":{"type":["string","null"],"maxLength":2000},"dismissedReason":{"type":["string","null"],"maxLength":2000},"actionedAt":{"type":["string","null"],"format":"date-time"},"actionedBy":{"type":["object","null"],"properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"User who actioned the observation"},"actionNotes":{"type":["string","null"],"maxLength":2000},"raisedLatitude":{"type":["number","null"],"minimum":-90,"maximum":90,"description":"WGS-84 latitude in decimal degrees (-90 to 90)"},"raisedLongitude":{"type":["number","null"],"minimum":-180,"maximum":180,"description":"WGS-84 longitude in decimal degrees (-180 to 180)"},"photos":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"fileUrl":{"type":"string","maxLength":2048,"format":"uri"},"mimeType":{"type":"string","maxLength":100},"fileSize":{"type":"integer","minimum":0},"uploadedBy":{"type":"object","properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"User who uploaded the photo"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","fileUrl","mimeType","fileSize","uploadedBy","createdAt"],"description":"Observation photo"},"maxItems":50},"comments":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"content":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"user":{"type":"object","properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"Comment author"},"userAvatarUrl":{"type":["string","null"],"maxLength":2048,"format":"uri"}},"required":["id","content","createdAt","user","userAvatarUrl"],"description":"Observation comment"},"maxItems":500},"transitions":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"fromStatus":{"type":"string","enum":["REPORTED","REVIEWED","ACTIONED","CLOSED","DISMISSED"]},"toStatus":{"type":"string","enum":["REPORTED","REVIEWED","ACTIONED","CLOSED","DISMISSED"]},"userId":{"type":"string","format":"uuid"},"notes":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"}},"required":["id","fromStatus","toStatus","userId","notes","createdAt"],"description":"Observation status transition"},"maxItems":100}},"required":["id","observationType","title","description","severity","status","raisedAt","raisedBy","site","assignedTo","photosCount","commentsCount","notes","dismissedReason","actionedAt","actionedBy","actionNotes","raisedLatitude","raisedLongitude","photos","comments"],"description":"Observation detail response"}},"required":["success","data"],"description":"Standard API success response"}}}},"404":{"description":"Observation not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}},"patch":{"operationId":"updateObservation","summary":"Update observation","description":"Updates observation details such as severity, description, or assigned user. Site-role holders with `observation.review` capability can edit observations at their site; service-layer site-scoping enforced.","tags":["Observations"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":255},"description":{"type":"string","maxLength":2000},"severity":{"type":"string","enum":["LOW","MEDIUM","HIGH","CRITICAL"]},"observationType":{"type":"string","enum":["HAZARD","NEAR_MISS","UNSAFE_ACT","UNSAFE_CONDITION","POSITIVE","OTHER"]},"notes":{"type":"string","maxLength":2000},"assignedToUserId":{"type":["string","null"],"format":"uuid"}},"additionalProperties":false,"description":"Update an existing observation"}}}},"responses":{"200":{"description":"Observation updated","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"observationType":{"type":"string","enum":["HAZARD","NEAR_MISS","UNSAFE_ACT","UNSAFE_CONDITION","POSITIVE","OTHER"]},"title":{"type":"string"},"description":{"type":"string","maxLength":2000},"severity":{"type":"string","enum":["LOW","MEDIUM","HIGH","CRITICAL"]},"status":{"type":"string","enum":["REPORTED","REVIEWED","ACTIONED","CLOSED","DISMISSED"]},"raisedAt":{"type":"string","format":"date-time"},"raisedBy":{"type":"object","properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"User who raised the observation"},"site":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"}},"required":["id","name"],"description":"Site where the observation was raised"},"assignedTo":{"type":["object","null"],"properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"User assigned to the observation"},"photosCount":{"type":"integer"},"commentsCount":{"type":"integer"},"scanSource":{"type":["string","null"],"enum":["qr","nfc","serial",null],"description":"How the user reached the equipment-anchored action: QR scan, NFC tap, or manual serial entry."}},"required":["id","observationType","title","description","severity","status","raisedAt","raisedBy","site","assignedTo","photosCount","commentsCount"],"description":"Observation list item response"}},"required":["success","data"],"description":"Standard API success response"}}}}}},"delete":{"operationId":"deleteObservation","summary":"Delete observation (soft-delete)","description":"Soft-deletes an observation.","tags":["Observations"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"responses":{"204":{"description":"Observation deleted"},"404":{"description":"Observation not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}}},"/api/v1/observations/:id/transition":{"post":{"operationId":"transitionObservation","summary":"Transition observation status","description":"Advances an observation to a new status in the workflow. Per-transition RBAC is enforced in the service layer.","tags":["Observations"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"toStatus":{"type":"string","enum":["REPORTED","REVIEWED","ACTIONED","CLOSED","DISMISSED"]},"notes":{"type":"string","maxLength":2000},"dismissedReason":{"type":"string","maxLength":2000}},"required":["toStatus"],"additionalProperties":false,"description":"Transition an observation status"}}}},"responses":{"200":{"description":"Observation transitioned","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"observationType":{"type":"string","enum":["HAZARD","NEAR_MISS","UNSAFE_ACT","UNSAFE_CONDITION","POSITIVE","OTHER"]},"title":{"type":"string"},"description":{"type":"string","maxLength":2000},"severity":{"type":"string","enum":["LOW","MEDIUM","HIGH","CRITICAL"]},"status":{"type":"string","enum":["REPORTED","REVIEWED","ACTIONED","CLOSED","DISMISSED"]},"raisedAt":{"type":"string","format":"date-time"},"raisedBy":{"type":"object","properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"User who raised the observation"},"site":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"}},"required":["id","name"],"description":"Site where the observation was raised"},"assignedTo":{"type":["object","null"],"properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"User assigned to the observation"},"photosCount":{"type":"integer"},"commentsCount":{"type":"integer"},"scanSource":{"type":["string","null"],"enum":["qr","nfc","serial",null],"description":"How the user reached the equipment-anchored action: QR scan, NFC tap, or manual serial entry."}},"required":["id","observationType","title","description","severity","status","raisedAt","raisedBy","site","assignedTo","photosCount","commentsCount"],"description":"Observation list item response"}},"required":["success","data"],"description":"Standard API success response"}}}},"404":{"description":"Observation not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}}},"/api/v1/observations/:id/photos":{"post":{"operationId":"createObservationPhoto","summary":"Add photo to observation","description":"Attaches a photo to an observation.","tags":["Observations"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"fileUrl":{"type":"string","maxLength":2048,"format":"uri"},"mimeType":{"type":"string","enum":["image/jpeg","image/png","image/webp","image/gif","image/heic","image/heif","application/pdf","text/csv","application/vnd.openxmlformats-officedocument.spreadsheetml.sheet","application/vnd.ms-excel"],"description":"Allowed MIME types for file uploads"},"fileSize":{"type":"integer","minimum":0,"maximum":52428800}},"required":["fileUrl","mimeType","fileSize"],"additionalProperties":false,"description":"Attach a photo to an observation"}}}},"responses":{"201":{"description":"Photo attached to observation","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"fileUrl":{"type":"string","maxLength":2048,"format":"uri"},"mimeType":{"type":"string","maxLength":100},"fileSize":{"type":"integer","minimum":0},"uploadedBy":{"type":"object","properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"A person: the name this org shows for them, where that name came from, and the contact that tells two same-named people apart"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","fileUrl","mimeType","fileSize","uploadedBy","createdAt"],"description":"Observation photo response with uploader info"}},"required":["success","data"],"description":"Standard API success response"}}}},"404":{"description":"Observation not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}},"get":{"operationId":"listObservationPhotos","summary":"List observation photos","description":"Returns all photos attached to an observation.","tags":["Observations"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"List of observation photos","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"fileUrl":{"type":"string","maxLength":2048,"format":"uri"},"mimeType":{"type":"string","maxLength":100},"fileSize":{"type":"integer","minimum":0},"uploadedBy":{"type":"object","properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"A person: the name this org shows for them, where that name came from, and the contact that tells two same-named people apart"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","fileUrl","mimeType","fileSize","uploadedBy","createdAt"],"description":"Observation photo response with uploader info"}}},"required":["success","data"],"description":"Standard API success response"}}}},"404":{"description":"Observation not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}}},"/api/v1/observations/:id/comments":{"post":{"operationId":"createObservationComment","summary":"Add comment to observation","description":"Adds a comment to an observation.","tags":["Observations"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"content":{"type":"string","minLength":1,"maxLength":5000}},"required":["content"],"additionalProperties":false,"description":"Add a comment to an observation"}}}},"responses":{"201":{"description":"Comment added to observation","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"orgId":{"type":"string","format":"uuid"},"observationId":{"type":"string","format":"uuid"},"createdByUserId":{"type":"string","format":"uuid"},"content":{"type":"string","minLength":1,"maxLength":5000},"createdAt":{"type":["string","null"],"format":"date-time"},"updatedAt":{"type":["string","null"],"format":"date-time"},"deletedAt":{"type":["string","null"],"format":"date-time"},"updatedByUserId":{"type":["string","null"],"format":"uuid"},"deletedByUserId":{"type":["string","null"],"format":"uuid"}},"required":["id","orgId","observationId","createdByUserId","content","createdAt","updatedAt"],"description":"Comment on an observation"}},"required":["success","data"],"description":"Standard API success response"}}}},"404":{"description":"Observation not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}},"get":{"operationId":"listObservationComments","summary":"List observation comments","description":"Returns all comments on an observation.","tags":["Observations"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"List of observation comments","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"content":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"user":{"type":"object","properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"nameSource":{"type":"string","enum":["ORG","PERSON","NONE"],"description":"Which layer supplied the displayed name"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["userId","name","nameSource","email","phone"],"description":"Comment author"},"userAvatarUrl":{"type":["string","null"],"maxLength":2048,"format":"uri"}},"required":["id","content","createdAt","user","userAvatarUrl"],"description":"Observation comment"}}},"required":["success","data"],"description":"Standard API success response"}}}},"404":{"description":"Observation not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}}},"/api/v1/observations/:id/comments/:commentId":{"patch":{"operationId":"updateObservationComment","summary":"Update observation comment","description":"Updates an observation comment.","tags":["Observations"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"commentId","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"content":{"type":"string","minLength":1,"maxLength":5000}},"required":["content"],"additionalProperties":false,"description":"Update an observation comment"}}}},"responses":{"200":{"description":"Comment updated","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"orgId":{"type":"string","format":"uuid"},"observationId":{"type":"string","format":"uuid"},"createdByUserId":{"type":"string","format":"uuid"},"content":{"type":"string","minLength":1,"maxLength":5000},"createdAt":{"type":["string","null"],"format":"date-time"},"updatedAt":{"type":["string","null"],"format":"date-time"},"deletedAt":{"type":["string","null"],"format":"date-time"},"updatedByUserId":{"type":["string","null"],"format":"uuid"},"deletedByUserId":{"type":["string","null"],"format":"uuid"}},"required":["id","orgId","observationId","createdByUserId","content","createdAt","updatedAt"],"description":"Comment on an observation"}},"required":["success","data"],"description":"Standard API success response"}}}},"404":{"description":"Comment not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}},"delete":{"operationId":"deleteObservationComment","summary":"Delete observation comment","description":"Soft-deletes an observation comment.","tags":["Observations"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"commentId","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"idempotency-key","in":"header"}],"responses":{"204":{"description":"Comment deleted"},"404":{"description":"Comment not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["ADDON_NOT_APPLICABLE_TO_PLAN","ADDON_REQUIRES_PAID_PLAN","ADDON_REVOKE_SOURCE_FORBIDDEN","ADDON_SOURCE_FORBIDDEN","APP_VERSION_TOO_OLD","AUTH_ERROR","BAD_REQUEST","BILLING_CONSENT_REQUIRED","BUSINESS_RULE","CHECKOUT_REQUIRED","COMMAND_IN_FLIGHT","CONCURRENT_MODIFICATION","CONFLICT","DEPENDENCY_UNAVAILABLE","DUPLICATE_ENTRY","EMAIL_NOT_VERIFIED","EQUIPMENT_NOT_ACTIVE","FEATURE_DISABLED","FORBIDDEN","GLOBAL_FEATURE_DISABLED","IDEMPOTENCY_CONFLICT","INSUFFICIENT_ROLE","INTERNAL_ERROR","INVALID_STATE_TRANSITION","KIOSK_NOT_ALLOWED","MFA_REQUIRED","NOT_FOUND","OPERATIONAL_TOGGLE","PAYMENT_REQUIRED","RATE_LIMITED","RESOURCE_NOT_FOUND","SERVICE_UNAVAILABLE","SESSION_IDLE_EXPIRED","SESSION_MAX_AGE_EXCEEDED","SSO_REQUIRED","SUBSCRIPTION_INACTIVE","SUBSCRIPTION_LIMIT_EXCEEDED","SYSTEM_ROLE_REQUIRED","TAG_DEACTIVATED","TIER_CHANGE_NOT_ALLOWED","TIER_CHANGE_REQUIRES_STRIPE","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REVOKED","UNAUTHORIZED","UNPROCESSABLE","VALIDATION_ERROR"]},"message":{"type":"string"},"requestId":{"type":"string"},"messageKey":{"type":"string"},"details":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"description":"Single validation error issue"}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}},{"type":"array","items":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}]}}}]}}]}},"required":["code","message","requestId"]}},"required":["success","error"],"description":"Error response"}}}}}}}},"webhooks":{}}