openapi: 3.0.3 info: title: TrackLab description: '' version: 1.0.0 servers: - url: 'https://tracklabsolar.com' tags: - name: 'Admin Management' description: "\nAPIs for super admin operations" - name: Authentication description: "\nAPIs for managing authentication sessions" - name: 'Authentication > Token Management' description: '' - name: 'Company - Data Retention' description: '' - name: 'Company Activity Logs' description: '' - name: 'Company Management' description: "\nAPIs for managing company information" - name: 'Company User Management' description: '' - name: 'Document Types' description: '' - name: Documents description: '' - name: Endpoints description: '' - name: Invitations description: '' - name: 'Super Admin - Activity Logs' description: '' - name: 'Super Admin - Company Users' description: '' - name: 'Super Admin - Data Retention' description: '' - name: 'Super Admin - Impersonation' description: '' - name: 'Super Admin - TrackLab Users' description: '' - name: 'Super Admin - Users' description: '' - name: 'Super Admin > Companies' description: '' - name: 'Super Admin > Mobile Audit Events' description: '' - name: 'Super Admin > Mobile Devices' description: '' - name: 'Super Admin > Routes' description: '' - name: System description: "\nAPIs for system testing and health checks" components: securitySchemes: default: type: http scheme: bearer description: 'You can retrieve your token by visiting your dashboard and clicking Generate API token.' security: - default: [] paths: /api/v1/sa/user: post: summary: 'Add New User' operationId: addNewUser description: 'Create a new user and company (super admin only).' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: uuid: 550e8400-e29b-41d4-a716-446655440000 email: user@example.com firstName: John lastName: Doe phoneNumbers: - countryIsoCode: US phoneNumber: '+1234567890' isChecked: true isValid: true createdAt: '2024-01-20T12:00:00Z' updatedAt: '2024-01-20T12:00:00Z' defaultCompanySlug: new-company-ltd emailVerifiedAt: null defaultCountryIsoCode: US defaultCountryEmoji: πŸ‡ΊπŸ‡Έ imgUrl: 'https://www.gravatar.com/avatar/...' imgThumbUrl: 'https://www.gravatar.com/avatar/...' properties: data: type: object properties: uuid: type: string example: 550e8400-e29b-41d4-a716-446655440000 email: type: string example: user@example.com firstName: type: string example: John lastName: type: string example: Doe phoneNumbers: type: array example: - countryIsoCode: US phoneNumber: '+1234567890' isChecked: true isValid: true items: type: object properties: countryIsoCode: type: string example: US phoneNumber: type: string example: '+1234567890' isChecked: type: boolean example: true isValid: type: boolean example: true createdAt: type: string example: '2024-01-20T12:00:00Z' updatedAt: type: string example: '2024-01-20T12:00:00Z' defaultCompanySlug: type: string example: new-company-ltd emailVerifiedAt: type: string example: null nullable: true defaultCountryIsoCode: type: string example: US defaultCountryEmoji: type: string example: πŸ‡ΊπŸ‡Έ imgUrl: type: string example: 'https://www.gravatar.com/avatar/...' imgThumbUrl: type: string example: 'https://www.gravatar.com/avatar/...' 422: description: '' content: application/json: schema: type: object example: message: 'The given data was invalid.' errors: email: - 'The email has already been taken.' companyName: - 'The company name has already been taken.' properties: message: type: string example: 'The given data was invalid.' errors: type: object properties: email: type: array example: - 'The email has already been taken.' items: type: string companyName: type: array example: - 'The company name has already been taken.' items: type: string tags: - 'Admin Management' requestBody: required: true content: application/json: schema: type: object properties: companyName: type: string description: 'The name of the company.' example: 'New Company Ltd' email: type: string description: "The user's email address." example: user@example.com firstName: type: string description: "The user's first name." example: John lastName: type: string description: "The user's last name." example: Doe nullable: true password: type: string description: "The user's password (min 10 characters)." example: SecurePass123! countryIsoCode: type: string description: "The ISO code of the user's country." example: US phoneNumber: type: string description: "The user's phone number." example: '+1234567890' required: - companyName - email - firstName - lastName - password - countryIsoCode - phoneNumber /api/v1/login: post: summary: 'Login user' operationId: loginUser description: "Authenticate a user and create a new session. This endpoint validates the user's\ncredentials and returns the authenticated user's details along with a session cookie." parameters: [] responses: 200: description: '' content: application/json: schema: oneOf: - description: '' type: object example: data: uuid: b11fab33-a56a-4a78-a3c1-b9d324c6aacd createdAt: '2025-11-12T20:27:08+00:00' updatedAt: '2026-02-10T15:20:26+00:00' defaultCompanySlug: null emailVerifiedAt: null defaultCountryIsoCode: '' defaultCountryEmoji: '' email: liquid.ideas@gmail.com firstName: Jo lastName: Whitehouse phoneNumbers: [] roles: [] imgUrl: null imgThumbUrl: null imgLargeUrl: null imgUrlExpiresAt: null isActive: true disabledAt: null status: null statusName: null properties: data: type: object properties: uuid: type: string example: b11fab33-a56a-4a78-a3c1-b9d324c6aacd createdAt: type: string example: '2025-11-12T20:27:08+00:00' updatedAt: type: string example: '2026-02-10T15:20:26+00:00' defaultCompanySlug: type: string example: null nullable: true emailVerifiedAt: type: string example: null nullable: true defaultCountryIsoCode: type: string example: '' defaultCountryEmoji: type: string example: '' email: type: string example: liquid.ideas@gmail.com firstName: type: string example: Jo lastName: type: string example: Whitehouse phoneNumbers: type: array example: [] roles: type: array example: [] imgUrl: type: string example: null nullable: true imgThumbUrl: type: string example: null nullable: true imgLargeUrl: type: string example: null nullable: true imgUrlExpiresAt: type: string example: null nullable: true isActive: type: boolean example: true disabledAt: type: string example: null nullable: true status: type: string example: null nullable: true statusName: type: string example: null nullable: true - description: Success type: object example: data: uuid: 550e8400-e29b-41d4-a716-446655440000 email: john@example.com firstName: John lastName: Doe phoneNumbers: - countryIsoCode: GB phoneNumber: +44... isChecked: true isValid: true createdAt: '2024-01-20T12:00:00Z' updatedAt: '2024-01-20T12:00:00Z' imgUrl: 'https://example.com/profiles/john.jpg' imgThumbUrl: 'https://example.com/profiles/john_thumb.jpg' defaultCompanySlug: example-company emailVerifiedAt: '2024-01-20T11:00:00Z' defaultCountryIsoCode: GB defaultCountryEmoji: πŸ‡¬πŸ‡§ properties: data: type: object properties: uuid: type: string example: 550e8400-e29b-41d4-a716-446655440000 email: type: string example: john@example.com firstName: type: string example: John lastName: type: string example: Doe phoneNumbers: type: array example: - countryIsoCode: GB phoneNumber: +44... isChecked: true isValid: true items: type: object properties: countryIsoCode: type: string example: GB phoneNumber: type: string example: +44... isChecked: type: boolean example: true isValid: type: boolean example: true createdAt: type: string example: '2024-01-20T12:00:00Z' updatedAt: type: string example: '2024-01-20T12:00:00Z' imgUrl: type: string example: 'https://example.com/profiles/john.jpg' imgThumbUrl: type: string example: 'https://example.com/profiles/john_thumb.jpg' defaultCompanySlug: type: string example: example-company emailVerifiedAt: type: string example: '2024-01-20T11:00:00Z' defaultCountryIsoCode: type: string example: GB defaultCountryEmoji: type: string example: πŸ‡¬πŸ‡§ 422: description: '' content: application/json: schema: oneOf: - description: 'Invalid Credentials' type: object example: message: 'The provided credentials are incorrect.' errors: email: - 'These credentials do not match our records.' properties: message: type: string example: 'The provided credentials are incorrect.' errors: type: object properties: email: type: array example: - 'These credentials do not match our records.' items: type: string - description: 'Invalid Credentials' type: object example: message: 'The provided credentials are incorrect.' errors: email: - 'These credentials do not match our records.' properties: message: type: string example: 'The provided credentials are incorrect.' errors: type: object properties: email: type: array example: - 'These credentials do not match our records.' items: type: string 429: description: 'Too Many Attempts' content: application/json: schema: type: object example: message: 'Too many login attempts. Please try again in 60 seconds.' errors: email: - 'Too many login attempts.' properties: message: type: string example: 'Too many login attempts. Please try again in 60 seconds.' errors: type: object properties: email: type: array example: - 'Too many login attempts.' items: type: string tags: - Authentication requestBody: required: true content: application/json: schema: type: object properties: email: type: string description: "The user's email address." example: john@example.com password: type: string description: "The user's password (min 10 characters)." example: 'secret123!@#' remember_me: type: boolean description: 'Remember the session for extended period (30 days).' example: true required: - email - password security: [] /api/v1/logout: get: summary: 'Logout user' operationId: logoutUser description: "Invalidate the current user's session." parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: msg: 'Logged out' properties: msg: type: string example: 'Logged out' 204: description: '' content: application/json: schema: type: object example: { } properties: { } 401: description: Unauthenticated content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Authentication /api/v1/logout/everywhere: delete: summary: '' operationId: deleteApiV1LogoutEverywhere description: '' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: message: 'Logged out everywhere - all tokens and sessions invalidated' properties: data: type: object properties: message: type: string example: 'Logged out everywhere - all tokens and sessions invalidated' tags: - 'Authentication > Token Management' /api/v1/sanctum/token: post: summary: '' operationId: postApiV1SanctumToken description: '' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: accessToken: 1|sanctum_abc refreshToken: 2|sanctum_xyz tokenType: Bearer expiresIn: 900 properties: data: type: object properties: accessToken: type: string example: 1|sanctum_abc refreshToken: type: string example: 2|sanctum_xyz tokenType: type: string example: Bearer expiresIn: type: integer example: 900 tags: - 'Authentication > Token Management' requestBody: required: true content: application/json: schema: type: object properties: email: type: string description: 'User email address. Must be a valid email address.' example: user@example.com password: type: string description: 'User password.' example: SecurePass123! deviceName: type: string description: 'Name of the device requesting the token. Must not be greater than 255 characters.' example: 'TrackLab Web' abilities: type: object description: 'Optional token abilities (defaults to ["*"]).' example: - 'deliveries:read' properties: { } expiresIn: type: integer description: 'Access token lifetime in minutes. Must be at least 1.' example: 1440 refreshExpiresIn: type: integer description: 'Refresh token lifetime in minutes. Must be at least 1.' example: 10080 required: - email - password - deviceName /api/v1/sanctum/token/refresh: post: summary: '' operationId: postApiV1SanctumTokenRefresh description: '' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: accessToken: 3|sanctum_new refreshToken: 4|sanctum_new_refresh tokenType: Bearer expiresIn: 900 properties: data: type: object properties: accessToken: type: string example: 3|sanctum_new refreshToken: type: string example: 4|sanctum_new_refresh tokenType: type: string example: Bearer expiresIn: type: integer example: 900 tags: - 'Authentication > Token Management' requestBody: required: true content: application/json: schema: type: object properties: refreshToken: type: string description: 'Refresh token issued during login.' example: 2|laravel_sanctum_abc123 expiresIn: type: integer description: 'New access token lifetime in minutes. Must be at least 1.' example: 1440 refreshExpiresIn: type: integer description: 'New refresh token lifetime in minutes. Must be at least 1.' example: 10080 required: - refreshToken delete: summary: '' operationId: deleteApiV1SanctumTokenRefresh description: '' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: message: 'Refresh token revoked successfully' properties: data: type: object properties: message: type: string example: 'Refresh token revoked successfully' tags: - 'Authentication > Token Management' requestBody: required: true content: application/json: schema: type: object properties: refreshToken: type: string description: 'Refresh token to revoke.' example: 2|laravel_sanctum_abc123 required: - refreshToken /api/v1/sanctum/token/current: delete: summary: '' operationId: deleteApiV1SanctumTokenCurrent description: '' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: message: 'Current token revoked successfully' properties: data: type: object properties: message: type: string example: 'Current token revoked successfully' tags: - 'Authentication > Token Management' /api/v1/sanctum/token/all: delete: summary: '' operationId: deleteApiV1SanctumTokenAll description: '' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: message: 'All other tokens revoked successfully' properties: data: type: object properties: message: type: string example: 'All other tokens revoked successfully' tags: - 'Authentication > Token Management' /api/v1/sanctum/tokens: get: summary: '' operationId: getApiV1SanctumTokens description: '' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: tokens: - tokenUuid: 550e8400-e29b-41d4-a716-446655440000 name: 'TrackLab Web' abilities: - '*' lastUsedAt: '2024-01-20T12:00:00Z' createdAt: '2024-01-19T12:00:00Z' expiresAt: '2024-02-18T12:00:00Z' isRefreshToken: false properties: data: type: object properties: tokens: type: array example: - tokenUuid: 550e8400-e29b-41d4-a716-446655440000 name: 'TrackLab Web' abilities: - '*' lastUsedAt: '2024-01-20T12:00:00Z' createdAt: '2024-01-19T12:00:00Z' expiresAt: '2024-02-18T12:00:00Z' isRefreshToken: false items: type: object properties: tokenUuid: type: string example: 550e8400-e29b-41d4-a716-446655440000 name: type: string example: 'TrackLab Web' abilities: type: array example: - '*' items: type: string lastUsedAt: type: string example: '2024-01-20T12:00:00Z' createdAt: type: string example: '2024-01-19T12:00:00Z' expiresAt: type: string example: '2024-02-18T12:00:00Z' isRefreshToken: type: boolean example: false tags: - 'Authentication > Token Management' '/api/v1/sanctum/token/{tokenUuid}': delete: summary: '' operationId: deleteApiV1SanctumTokenTokenUuid description: '' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: message: 'Token revoked.' properties: data: type: object properties: message: type: string example: 'Token revoked.' tags: - 'Authentication > Token Management' requestBody: required: true content: application/json: schema: type: object properties: tokenUuid: type: string description: 'Must be a valid UUID.' example: 4e350ee3-9ebc-34ec-97c2-290726ff51c8 required: - tokenUuid parameters: - in: path name: tokenUuid description: '' example: 5025355b-693f-384c-8140-9e85d38297c7 required: true schema: type: string '/api/v1/c/{company_slug}/data-retention/policies': get: summary: 'List all effective retention policies for the authenticated company.' operationId: listAllEffectiveRetentionPoliciesForTheAuthenticatedCompany description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - 'Company - Data Retention' parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string '/api/v1/c/{company_slug}/data-retention/policies/{dataRetentionDataType_slug}': get: summary: 'Show a single effective retention policy for the authenticated company.' operationId: showASingleEffectiveRetentionPolicyForTheAuthenticatedCompany description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - 'Company - Data Retention' parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: dataRetentionDataType_slug description: 'The slug of the dataRetentionDataType.' example: collector-measurements required: true schema: type: string '/api/v1/c/{company_slug}/activity-logs': get: summary: 'List activity logs for the company.' operationId: listActivityLogsForTheCompany description: "Returns paginated activity logs for actions performed by users\nwithin the authenticated company." parameters: - in: query name: page description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 required: false schema: type: integer description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 - in: query name: perPage description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 25 required: false schema: type: integer description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 25 - in: query name: event description: 'Filter by event category. Must not be greater than 255 characters.' example: farm-section required: false schema: type: string description: 'Filter by event category. Must not be greater than 255 characters.' example: farm-section nullable: true - in: query name: action description: 'Filter by action type (e.g., "create", "update", "delete"). Must not be greater than 255 characters.' example: update required: false schema: type: string description: 'Filter by action type (e.g., "create", "update", "delete"). Must not be greater than 255 characters.' example: update nullable: true - in: query name: logName description: 'Filter by log channel name. Must not be greater than 255 characters.' example: default required: false schema: type: string description: 'Filter by log channel name. Must not be greater than 255 characters.' example: default nullable: true - in: query name: subjectType description: 'Filter by affected model type (short name, e.g., "Farm", "Collector"). Must not be greater than 255 characters.' example: Farm required: false schema: type: string description: 'Filter by affected model type (short name, e.g., "Farm", "Collector"). Must not be greater than 255 characters.' example: Farm nullable: true - in: query name: causerUuid description: 'Filter by the UUID of a company user who performed the action. Must be a valid UUID.' example: 550e8400-e29b-41d4-a716-446655440000 required: false schema: type: string description: 'Filter by the UUID of a company user who performed the action. Must be a valid UUID.' example: 550e8400-e29b-41d4-a716-446655440000 nullable: true - in: query name: fromDate description: 'Filter activities from this date (ISO 8601 format). Must be a valid date.' example: '2026-01-01' required: false schema: type: string description: 'Filter activities from this date (ISO 8601 format). Must be a valid date.' example: '2026-01-01' nullable: true - in: query name: toDate description: 'Filter activities up to this date (ISO 8601 format). Must be a valid date. Must be a date after or equal to fromDate.' example: '2026-12-31' required: false schema: type: string description: 'Filter activities up to this date (ISO 8601 format). Must be a valid date. Must be a date after or equal to fromDate.' example: '2026-12-31' nullable: true - in: query name: batchUuid description: 'Filter by batch UUID to get related activities. Must be a valid UUID.' example: 550e8400-e29b-41d4-a716-446655440000 required: false schema: type: string description: 'Filter by batch UUID to get related activities. Must be a valid UUID.' example: 550e8400-e29b-41d4-a716-446655440000 nullable: true - in: query name: search description: 'Search in properties, description, and event fields. Must not be greater than 255 characters.' example: collector required: false schema: type: string description: 'Search in properties, description, and event fields. Must not be greater than 255 characters.' example: collector nullable: true - in: query name: sortBy description: 'Field to sort by (created_at, event, description, log_name).' example: created_at required: false schema: type: string description: 'Field to sort by (created_at, event, description, log_name).' example: created_at enum: - created_at - event - description - log_name nullable: true - in: query name: sortOrder description: 'Sort direction (asc, desc).' example: desc required: false schema: type: string description: 'Sort direction (asc, desc).' example: desc enum: - asc - desc nullable: true responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - 'Company Activity Logs' parameters: - in: path name: company_slug description: 'The slug of the company.' example: voluptatem required: true schema: type: string '/api/v1/c/{company_slug}/activity-logs/filter-options': get: summary: 'Get available filter options for company activity logs.' operationId: getAvailableFilterOptionsForCompanyActivityLogs description: "Returns distinct values for events, log names, and subject types\nto populate filter dropdowns in the UI. Note: These are global values,\nnot filtered by company scope." parameters: - in: query name: page description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 required: false schema: type: integer description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 - in: query name: perPage description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 25 required: false schema: type: integer description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 25 - in: query name: event description: 'Filter by event category. Must not be greater than 255 characters.' example: farm-section required: false schema: type: string description: 'Filter by event category. Must not be greater than 255 characters.' example: farm-section nullable: true - in: query name: action description: 'Filter by action type (e.g., "create", "update", "delete"). Must not be greater than 255 characters.' example: update required: false schema: type: string description: 'Filter by action type (e.g., "create", "update", "delete"). Must not be greater than 255 characters.' example: update nullable: true - in: query name: logName description: 'Filter by log channel name. Must not be greater than 255 characters.' example: default required: false schema: type: string description: 'Filter by log channel name. Must not be greater than 255 characters.' example: default nullable: true - in: query name: subjectType description: 'Filter by affected model type (short name, e.g., "Farm", "Collector"). Must not be greater than 255 characters.' example: Farm required: false schema: type: string description: 'Filter by affected model type (short name, e.g., "Farm", "Collector"). Must not be greater than 255 characters.' example: Farm nullable: true - in: query name: causerUuid description: 'Filter by the UUID of a company user who performed the action. Must be a valid UUID.' example: 550e8400-e29b-41d4-a716-446655440000 required: false schema: type: string description: 'Filter by the UUID of a company user who performed the action. Must be a valid UUID.' example: 550e8400-e29b-41d4-a716-446655440000 nullable: true - in: query name: fromDate description: 'Filter activities from this date (ISO 8601 format). Must be a valid date.' example: '2026-01-01' required: false schema: type: string description: 'Filter activities from this date (ISO 8601 format). Must be a valid date.' example: '2026-01-01' nullable: true - in: query name: toDate description: 'Filter activities up to this date (ISO 8601 format). Must be a valid date. Must be a date after or equal to fromDate.' example: '2026-12-31' required: false schema: type: string description: 'Filter activities up to this date (ISO 8601 format). Must be a valid date. Must be a date after or equal to fromDate.' example: '2026-12-31' nullable: true - in: query name: batchUuid description: 'Filter by batch UUID to get related activities. Must be a valid UUID.' example: 550e8400-e29b-41d4-a716-446655440000 required: false schema: type: string description: 'Filter by batch UUID to get related activities. Must be a valid UUID.' example: 550e8400-e29b-41d4-a716-446655440000 nullable: true - in: query name: search description: 'Search in properties, description, and event fields. Must not be greater than 255 characters.' example: collector required: false schema: type: string description: 'Search in properties, description, and event fields. Must not be greater than 255 characters.' example: collector nullable: true - in: query name: sortBy description: 'Field to sort by (created_at, event, description, log_name).' example: created_at required: false schema: type: string description: 'Field to sort by (created_at, event, description, log_name).' example: created_at enum: - created_at - event - description - log_name nullable: true - in: query name: sortOrder description: 'Sort direction (asc, desc).' example: desc required: false schema: type: string description: 'Sort direction (asc, desc).' example: desc enum: - asc - desc nullable: true responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - 'Company Activity Logs' parameters: - in: path name: company_slug description: 'The slug of the company.' example: commodi required: true schema: type: string '/api/v1/c/{company_slug}/activity-logs/export': get: summary: 'Export activity logs for the company.' operationId: exportActivityLogsForTheCompany description: "Exports activity logs with optional filtering. Supports CSV and JSON formats.\nUses streaming for memory-efficient export of large datasets." parameters: - in: query name: startDate description: 'Filter activities from this date (ISO 8601 format). Must be a valid date.' example: '2026-01-01' required: false schema: type: string description: 'Filter activities from this date (ISO 8601 format). Must be a valid date.' example: '2026-01-01' nullable: true - in: query name: endDate description: 'Filter activities up to this date (ISO 8601 format). Must be a valid date. Must be a date after or equal to startDate.' example: '2026-12-31' required: false schema: type: string description: 'Filter activities up to this date (ISO 8601 format). Must be a valid date. Must be a date after or equal to startDate.' example: '2026-12-31' nullable: true - in: query name: event description: 'Filter by event category (e.g., "sa.device-model-type"). Must not be greater than 255 characters.' example: sa.device-model-type required: false schema: type: string description: 'Filter by event category (e.g., "sa.device-model-type"). Must not be greater than 255 characters.' example: sa.device-model-type nullable: true - in: query name: action description: 'Filter by action type (e.g., "create", "update", "delete"). Must not be greater than 255 characters.' example: create required: false schema: type: string description: 'Filter by action type (e.g., "create", "update", "delete"). Must not be greater than 255 characters.' example: create nullable: true - in: query name: logName description: 'Filter by log channel name. Must not be greater than 255 characters.' example: default required: false schema: type: string description: 'Filter by log channel name. Must not be greater than 255 characters.' example: default nullable: true - in: query name: subjectType description: 'Filter by affected model type (short name, e.g., "User", "Farm"). Must not be greater than 255 characters.' example: User required: false schema: type: string description: 'Filter by affected model type (short name, e.g., "User", "Farm"). Must not be greater than 255 characters.' example: User nullable: true - in: query name: causerUuid description: 'Filter by the UUID of the user who performed the action. Must be a valid UUID.' example: 550e8400-e29b-41d4-a716-446655440000 required: false schema: type: string description: 'Filter by the UUID of the user who performed the action. Must be a valid UUID.' example: 550e8400-e29b-41d4-a716-446655440000 nullable: true - in: query name: batchUuid description: 'Filter by batch UUID to get related activities. Must be a valid UUID.' example: 550e8400-e29b-41d4-a716-446655440000 required: false schema: type: string description: 'Filter by batch UUID to get related activities. Must be a valid UUID.' example: 550e8400-e29b-41d4-a716-446655440000 nullable: true - in: query name: search description: 'Search in properties, description, and event fields. Must not be greater than 255 characters.' example: firmware required: false schema: type: string description: 'Search in properties, description, and event fields. Must not be greater than 255 characters.' example: firmware nullable: true - in: query name: format description: 'Export format: csv or json (default: json).' example: csv required: false schema: type: string description: 'Export format: csv or json (default: json).' example: csv enum: - csv - json nullable: true responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - 'Company Activity Logs' parameters: - in: path name: company_slug description: 'The slug of the company.' example: ipsum required: true schema: type: string '/api/v1/c/{company_slug}': get: summary: 'Get Company Details' operationId: getCompanyDetails description: "Retrieve the authenticated user's company details." parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: slug: example-company createdAt: '2024-01-20T12:00:00Z' updatedAt: '2024-01-20T12:00:00Z' enabled: true defaultCountryIsoCode: ZA name: 'Example Company' logoUrl: 'https://api.example.com/api/v1/c/example-company/logo/256' logoThumbUrl: 'https://api.example.com/api/v1/c/example-company/logo/48' logoLargeUrl: 'https://api.example.com/api/v1/c/example-company/logo/512' logoUrlExpiresAt: '2024-01-21T12:00:00Z' favicons: favicon16: 'https://api.example.com/api/v1/c/example-company/logo/16' favicon32: 'https://api.example.com/api/v1/c/example-company/logo/32' favicon48: 'https://api.example.com/api/v1/c/example-company/logo/48' appleTouchIcon: 'https://api.example.com/api/v1/c/example-company/logo/180' android192: 'https://api.example.com/api/v1/c/example-company/logo/192' android512: 'https://api.example.com/api/v1/c/example-company/logo/512' properties: data: type: object properties: slug: type: string example: example-company createdAt: type: string example: '2024-01-20T12:00:00Z' updatedAt: type: string example: '2024-01-20T12:00:00Z' enabled: type: boolean example: true defaultCountryIsoCode: type: string example: ZA name: type: string example: 'Example Company' logoUrl: type: string example: 'https://api.example.com/api/v1/c/example-company/logo/256' logoThumbUrl: type: string example: 'https://api.example.com/api/v1/c/example-company/logo/48' logoLargeUrl: type: string example: 'https://api.example.com/api/v1/c/example-company/logo/512' logoUrlExpiresAt: type: string example: '2024-01-21T12:00:00Z' favicons: type: object properties: favicon16: type: string example: 'https://api.example.com/api/v1/c/example-company/logo/16' favicon32: type: string example: 'https://api.example.com/api/v1/c/example-company/logo/32' favicon48: type: string example: 'https://api.example.com/api/v1/c/example-company/logo/48' appleTouchIcon: type: string example: 'https://api.example.com/api/v1/c/example-company/logo/180' android192: type: string example: 'https://api.example.com/api/v1/c/example-company/logo/192' android512: type: string example: 'https://api.example.com/api/v1/c/example-company/logo/512' tags: - 'Company Management' patch: summary: 'Update Company Details' operationId: updateCompanyDetails description: "Update the authenticated company's basic details." parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: slug: example-company createdAt: '2024-01-20T12:00:00Z' updatedAt: '2024-01-21T12:00:00Z' enabled: true defaultCountryIsoCode: ZA name: 'Updated Example Company' logoUrl: null logoThumbUrl: null logoLargeUrl: null logoUrlExpiresAt: null favicons: null properties: data: type: object properties: slug: type: string example: example-company createdAt: type: string example: '2024-01-20T12:00:00Z' updatedAt: type: string example: '2024-01-21T12:00:00Z' enabled: type: boolean example: true defaultCountryIsoCode: type: string example: ZA name: type: string example: 'Updated Example Company' logoUrl: type: string example: null nullable: true logoThumbUrl: type: string example: null nullable: true logoLargeUrl: type: string example: null nullable: true logoUrlExpiresAt: type: string example: null nullable: true favicons: type: string example: null nullable: true tags: - 'Company Management' requestBody: required: true content: application/json: schema: type: object properties: name: type: string description: 'Company name. Must not be greater than 255 characters.' example: TrackLab required: - name parameters: - in: path name: company_slug description: 'The slug of the company.' example: atque required: true schema: type: string '/api/v1/c/{company_slug}/address': get: summary: '' operationId: getApiV1CCompany_slugAddress description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - 'Company Management' post: summary: '' operationId: postApiV1CCompany_slugAddress description: '' parameters: [] responses: { } tags: - 'Company Management' requestBody: required: true content: application/json: schema: type: object properties: addressString: type: string description: 'Full address as a single string. If provided, individual address fields are not required. Must not be greater than 500 characters.' example: '123 Main St, London SW1A 1AA' addressLine1: type: string description: 'First line of the address (required if addressString not provided). Must not be greater than 255 characters.' example: '123 Main Street' city: type: string description: 'City name (required if addressString not provided). Must not be greater than 255 characters.' example: London postCode: type: string description: 'Postal code (required if addressString not provided). Must not be greater than 20 characters.' example: 'SW1A 1AA' countryIsoCode: type: string description: 'Two-letter ISO country code. The iso_code of an existing record in the countries table.' example: GB addressLine2: type: string description: 'Second line of the address. Must not be greater than 255 characters.' example: 'Apt 4B' nullable: true neighborhood: type: string description: 'Neighborhood name. Must not be greater than 255 characters.' example: Westminster nullable: true locality: type: string description: 'Locality name. Must not be greater than 255 characters.' example: 'Central London' nullable: true place: type: string description: 'Place name. Must not be greater than 255 characters.' example: 'Piccadilly Circus' nullable: true district: type: string description: 'District name. Must not be greater than 255 characters.' example: 'City of Westminster' nullable: true region: type: string description: 'Region name. Must not be greater than 255 characters.' example: 'Greater London' nullable: true location: type: object description: 'Geographic coordinates (supports both latitude/longitude and lat/long formats).' example: lat: 51.5074 long: -0.1278 properties: latitude: type: number description: 'Latitude coordinate (required if location object is provided). This field is required when location is present.' example: 51.5074 longitude: type: number description: 'Longitude coordinate (required if location object is provided). This field is required when location is present.' example: -0.1278 nullable: true required: - addressLine1 - city - postCode - countryIsoCode parameters: - in: path name: company_slug description: 'The slug of the company.' example: corrupti required: true schema: type: string '/api/v1/c/{company_slug}/logo': post: summary: "Upload or replace the authenticated company's logo." operationId: uploadOrReplaceTheAuthenticatedCompanysLogo description: '' parameters: [] responses: { } tags: - 'Company Management' requestBody: required: true content: application/json: schema: type: object properties: file: type: string description: 'The image file to upload as the company logo.' example: veritatis required: - file delete: summary: "Delete the authenticated company's logo." operationId: deleteTheAuthenticatedCompanysLogo description: '' parameters: [] responses: { } tags: - 'Company Management' parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string '/api/v1/c/{company_slug}/logo/{format}': get: summary: "Get the authenticated company's logo in the requested format." operationId: getTheAuthenticatedCompanysLogoInTheRequestedFormat description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - 'Company Management' parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: format description: 'Optional parameter.' required: true schema: type: string examples: omitted: summary: 'When the value is omitted' value: '' present: summary: 'When the value is present' value: magnam '/api/v1/c/{company_slug}/user': get: summary: '' operationId: getApiV1CCompany_slugUser description: '' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: - uuid: b11fab33-a56a-4a78-a3c1-b9d324c6aacd createdAt: '2025-11-12T20:27:08+00:00' updatedAt: '2026-02-10T15:20:26+00:00' defaultCompanySlug: null emailVerifiedAt: null defaultCountryIsoCode: '' defaultCountryEmoji: '' email: liquid.ideas@gmail.com firstName: Jo lastName: Whitehouse phoneNumbers: [] roles: [] imgUrl: null imgThumbUrl: null imgLargeUrl: null imgUrlExpiresAt: null isActive: true disabledAt: null status: null statusName: null - uuid: b11fab33-a56a-4a78-a3c1-b9d324c6aacd createdAt: '2025-11-12T20:27:08+00:00' updatedAt: '2026-02-10T15:20:26+00:00' defaultCompanySlug: null emailVerifiedAt: null defaultCountryIsoCode: '' defaultCountryEmoji: '' email: liquid.ideas@gmail.com firstName: Jo lastName: Whitehouse phoneNumbers: [] roles: [] imgUrl: null imgThumbUrl: null imgLargeUrl: null imgUrlExpiresAt: null isActive: true disabledAt: null status: null statusName: null properties: data: type: array example: - uuid: b11fab33-a56a-4a78-a3c1-b9d324c6aacd createdAt: '2025-11-12T20:27:08+00:00' updatedAt: '2026-02-10T15:20:26+00:00' defaultCompanySlug: null emailVerifiedAt: null defaultCountryIsoCode: '' defaultCountryEmoji: '' email: liquid.ideas@gmail.com firstName: Jo lastName: Whitehouse phoneNumbers: [] roles: [] imgUrl: null imgThumbUrl: null imgLargeUrl: null imgUrlExpiresAt: null isActive: true disabledAt: null status: null statusName: null - uuid: b11fab33-a56a-4a78-a3c1-b9d324c6aacd createdAt: '2025-11-12T20:27:08+00:00' updatedAt: '2026-02-10T15:20:26+00:00' defaultCompanySlug: null emailVerifiedAt: null defaultCountryIsoCode: '' defaultCountryEmoji: '' email: liquid.ideas@gmail.com firstName: Jo lastName: Whitehouse phoneNumbers: [] roles: [] imgUrl: null imgThumbUrl: null imgLargeUrl: null imgUrlExpiresAt: null isActive: true disabledAt: null status: null statusName: null items: type: object properties: uuid: type: string example: b11fab33-a56a-4a78-a3c1-b9d324c6aacd createdAt: type: string example: '2025-11-12T20:27:08+00:00' updatedAt: type: string example: '2026-02-10T15:20:26+00:00' defaultCompanySlug: type: string example: null nullable: true emailVerifiedAt: type: string example: null nullable: true defaultCountryIsoCode: type: string example: '' defaultCountryEmoji: type: string example: '' email: type: string example: liquid.ideas@gmail.com firstName: type: string example: Jo lastName: type: string example: Whitehouse phoneNumbers: type: array example: [] roles: type: array example: [] imgUrl: type: string example: null nullable: true imgThumbUrl: type: string example: null nullable: true imgLargeUrl: type: string example: null nullable: true imgUrlExpiresAt: type: string example: null nullable: true isActive: type: boolean example: true disabledAt: type: string example: null nullable: true status: type: string example: null nullable: true statusName: type: string example: null nullable: true tags: - 'Company User Management' post: summary: '' operationId: postApiV1CCompany_slugUser description: '' parameters: [] responses: 201: description: '' content: application/json: schema: type: object example: data: uuid: b11fab33-a56a-4a78-a3c1-b9d324c6aacd createdAt: '2025-11-12T20:27:08+00:00' updatedAt: '2026-02-10T15:20:26+00:00' defaultCompanySlug: null emailVerifiedAt: null defaultCountryIsoCode: '' defaultCountryEmoji: '' email: liquid.ideas@gmail.com firstName: Jo lastName: Whitehouse phoneNumbers: [] roles: [] imgUrl: null imgThumbUrl: null imgLargeUrl: null imgUrlExpiresAt: null isActive: true disabledAt: null status: null statusName: null properties: data: type: object properties: uuid: type: string example: b11fab33-a56a-4a78-a3c1-b9d324c6aacd createdAt: type: string example: '2025-11-12T20:27:08+00:00' updatedAt: type: string example: '2026-02-10T15:20:26+00:00' defaultCompanySlug: type: string example: null nullable: true emailVerifiedAt: type: string example: null nullable: true defaultCountryIsoCode: type: string example: '' defaultCountryEmoji: type: string example: '' email: type: string example: liquid.ideas@gmail.com firstName: type: string example: Jo lastName: type: string example: Whitehouse phoneNumbers: type: array example: [] roles: type: array example: [] imgUrl: type: string example: null nullable: true imgThumbUrl: type: string example: null nullable: true imgLargeUrl: type: string example: null nullable: true imgUrlExpiresAt: type: string example: null nullable: true isActive: type: boolean example: true disabledAt: type: string example: null nullable: true status: type: string example: null nullable: true statusName: type: string example: null nullable: true 422: description: '' content: application/json: schema: type: object example: message: 'The email has already been taken.' properties: message: type: string example: 'The email has already been taken.' tags: - 'Company User Management' requestBody: required: true content: application/json: schema: type: object properties: email: type: string description: "The user's email address. Must be a valid email address. Must not be greater than 100 characters." example: admin@example.com firstName: type: string description: "The user's first name. Must be at least 2 characters. Must not be greater than 100 characters." example: John lastName: type: string description: "The user's last name. Must be at least 2 characters. Must not be greater than 100 characters." example: Doe countryIsoCode: type: string description: "The ISO code of the user's country. The iso_code of an existing record in the countries table." example: US phoneNumber: type: string description: "The user's phone number. Must be at least 6 characters." example: '+1234567890' role: type: string description: '' example: user enum: - owner - admin - user required: - email - firstName - countryIsoCode - phoneNumber parameters: - in: path name: company_slug description: 'The slug of the company.' example: omnis required: true schema: type: string '/api/v1/c/{company_slug}/user/role-uuids': get: summary: '' operationId: getApiV1CCompany_slugUserRoleUuids description: '' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: - 550e8400-e29b-41d4-a716-446655440000 - 7d793789-c8b3-4687-9287-c1e4c9c4b87b properties: data: type: array example: - 550e8400-e29b-41d4-a716-446655440000 - 7d793789-c8b3-4687-9287-c1e4c9c4b87b items: type: string tags: - 'Company User Management' parameters: - in: path name: company_slug description: 'The slug of the company.' example: non required: true schema: type: string '/api/v1/c/{company_slug}/user/{user_uuid}': get: summary: '' operationId: getApiV1CCompany_slugUserUser_uuid description: '' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: uuid: b11fab33-a56a-4a78-a3c1-b9d324c6aacd createdAt: '2025-11-12T20:27:08+00:00' updatedAt: '2026-02-10T15:20:26+00:00' defaultCompanySlug: null emailVerifiedAt: null defaultCountryIsoCode: '' defaultCountryEmoji: '' email: liquid.ideas@gmail.com firstName: Jo lastName: Whitehouse phoneNumbers: [] roles: [] imgUrl: null imgThumbUrl: null imgLargeUrl: null imgUrlExpiresAt: null isActive: true disabledAt: null status: null statusName: null properties: data: type: object properties: uuid: type: string example: b11fab33-a56a-4a78-a3c1-b9d324c6aacd createdAt: type: string example: '2025-11-12T20:27:08+00:00' updatedAt: type: string example: '2026-02-10T15:20:26+00:00' defaultCompanySlug: type: string example: null nullable: true emailVerifiedAt: type: string example: null nullable: true defaultCountryIsoCode: type: string example: '' defaultCountryEmoji: type: string example: '' email: type: string example: liquid.ideas@gmail.com firstName: type: string example: Jo lastName: type: string example: Whitehouse phoneNumbers: type: array example: [] roles: type: array example: [] imgUrl: type: string example: null nullable: true imgThumbUrl: type: string example: null nullable: true imgLargeUrl: type: string example: null nullable: true imgUrlExpiresAt: type: string example: null nullable: true isActive: type: boolean example: true disabledAt: type: string example: null nullable: true status: type: string example: null nullable: true statusName: type: string example: null nullable: true tags: - 'Company User Management' requestBody: required: true content: application/json: schema: type: object properties: user: type: string description: 'Must be a valid UUID.' example: a8e7bb49-aa3c-3c71-9cff-b08a3252d1ed required: - user patch: summary: '' operationId: patchApiV1CCompany_slugUserUser_uuid description: '' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: uuid: b11fab33-a56a-4a78-a3c1-b9d324c6aacd createdAt: '2025-11-12T20:27:08+00:00' updatedAt: '2026-02-10T15:20:26+00:00' defaultCompanySlug: null emailVerifiedAt: null defaultCountryIsoCode: '' defaultCountryEmoji: '' email: liquid.ideas@gmail.com firstName: Jo lastName: Whitehouse phoneNumbers: [] roles: [] imgUrl: null imgThumbUrl: null imgLargeUrl: null imgUrlExpiresAt: null isActive: true disabledAt: null status: null statusName: null properties: data: type: object properties: uuid: type: string example: b11fab33-a56a-4a78-a3c1-b9d324c6aacd createdAt: type: string example: '2025-11-12T20:27:08+00:00' updatedAt: type: string example: '2026-02-10T15:20:26+00:00' defaultCompanySlug: type: string example: null nullable: true emailVerifiedAt: type: string example: null nullable: true defaultCountryIsoCode: type: string example: '' defaultCountryEmoji: type: string example: '' email: type: string example: liquid.ideas@gmail.com firstName: type: string example: Jo lastName: type: string example: Whitehouse phoneNumbers: type: array example: [] roles: type: array example: [] imgUrl: type: string example: null nullable: true imgThumbUrl: type: string example: null nullable: true imgLargeUrl: type: string example: null nullable: true imgUrlExpiresAt: type: string example: null nullable: true isActive: type: boolean example: true disabledAt: type: string example: null nullable: true status: type: string example: null nullable: true statusName: type: string example: null nullable: true tags: - 'Company User Management' requestBody: required: true content: application/json: schema: type: object properties: user: type: string description: 'Must be a valid UUID.' example: d18f393a-5c44-345a-beff-d66e4a9d393c email: type: string description: 'User email address. Must be a valid email address. Must not be greater than 100 characters.' example: john.doe@example.com firstName: type: string description: 'User first name. Must be at least 2 characters. Must not be greater than 100 characters.' example: John lastName: type: string description: 'User last name. Must be at least 2 characters. Must not be greater than 100 characters.' example: Doe countryIsoCode: type: string description: 'ISO code of the user country. The iso_code of an existing record in the countries table.' example: US phoneNumber: type: string description: 'User phone number. Must be at least 6 characters.' example: '+1234567890' role: type: string description: 'User role (owner, admin, or user).' example: admin enum: - owner - admin - user required: - user delete: summary: '' operationId: deleteApiV1CCompany_slugUserUser_uuid description: '' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: success: true properties: success: type: boolean example: true tags: - 'Company User Management' requestBody: required: true content: application/json: schema: type: object properties: user: type: string description: 'Must be a valid UUID.' example: c9d947b1-9e6b-36ee-9540-0ba8a349d21e required: - user parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: user_uuid description: '' example: b11fab33-a56a-4a78-a3c1-b9d324c6aacd required: true schema: type: string '/api/v1/c/{company_slug}/user/{user_uuid}/disable': patch: summary: '' operationId: patchApiV1CCompany_slugUserUser_uuidDisable description: '' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: uuid: b11fab33-a56a-4a78-a3c1-b9d324c6aacd createdAt: '2025-11-12T20:27:08+00:00' updatedAt: '2026-02-10T15:20:26+00:00' defaultCompanySlug: null emailVerifiedAt: null defaultCountryIsoCode: '' defaultCountryEmoji: '' email: liquid.ideas@gmail.com firstName: Jo lastName: Whitehouse phoneNumbers: [] roles: [] imgUrl: null imgThumbUrl: null imgLargeUrl: null imgUrlExpiresAt: null isActive: true disabledAt: null status: null statusName: null properties: data: type: object properties: uuid: type: string example: b11fab33-a56a-4a78-a3c1-b9d324c6aacd createdAt: type: string example: '2025-11-12T20:27:08+00:00' updatedAt: type: string example: '2026-02-10T15:20:26+00:00' defaultCompanySlug: type: string example: null nullable: true emailVerifiedAt: type: string example: null nullable: true defaultCountryIsoCode: type: string example: '' defaultCountryEmoji: type: string example: '' email: type: string example: liquid.ideas@gmail.com firstName: type: string example: Jo lastName: type: string example: Whitehouse phoneNumbers: type: array example: [] roles: type: array example: [] imgUrl: type: string example: null nullable: true imgThumbUrl: type: string example: null nullable: true imgLargeUrl: type: string example: null nullable: true imgUrlExpiresAt: type: string example: null nullable: true isActive: type: boolean example: true disabledAt: type: string example: null nullable: true status: type: string example: null nullable: true statusName: type: string example: null nullable: true tags: - 'Company User Management' requestBody: required: true content: application/json: schema: type: object properties: user: type: string description: 'Must be a valid UUID.' example: 13460f35-347e-3bd9-8d21-71f506526333 required: - user parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: user_uuid description: '' example: b11fab33-a56a-4a78-a3c1-b9d324c6aacd required: true schema: type: string '/api/v1/c/{company_slug}/user/{user_uuid}/enable': patch: summary: '' operationId: patchApiV1CCompany_slugUserUser_uuidEnable description: '' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: uuid: b11fab33-a56a-4a78-a3c1-b9d324c6aacd createdAt: '2025-11-12T20:27:08+00:00' updatedAt: '2026-02-10T15:20:26+00:00' defaultCompanySlug: null emailVerifiedAt: null defaultCountryIsoCode: '' defaultCountryEmoji: '' email: liquid.ideas@gmail.com firstName: Jo lastName: Whitehouse phoneNumbers: [] roles: [] imgUrl: null imgThumbUrl: null imgLargeUrl: null imgUrlExpiresAt: null isActive: true disabledAt: null status: null statusName: null properties: data: type: object properties: uuid: type: string example: b11fab33-a56a-4a78-a3c1-b9d324c6aacd createdAt: type: string example: '2025-11-12T20:27:08+00:00' updatedAt: type: string example: '2026-02-10T15:20:26+00:00' defaultCompanySlug: type: string example: null nullable: true emailVerifiedAt: type: string example: null nullable: true defaultCountryIsoCode: type: string example: '' defaultCountryEmoji: type: string example: '' email: type: string example: liquid.ideas@gmail.com firstName: type: string example: Jo lastName: type: string example: Whitehouse phoneNumbers: type: array example: [] roles: type: array example: [] imgUrl: type: string example: null nullable: true imgThumbUrl: type: string example: null nullable: true imgLargeUrl: type: string example: null nullable: true imgUrlExpiresAt: type: string example: null nullable: true isActive: type: boolean example: true disabledAt: type: string example: null nullable: true status: type: string example: null nullable: true statusName: type: string example: null nullable: true tags: - 'Company User Management' requestBody: required: true content: application/json: schema: type: object properties: user: type: string description: 'Must be a valid UUID.' example: b21a8f07-1adc-3526-8408-e27d7660a700 required: - user parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: user_uuid description: '' example: b11fab33-a56a-4a78-a3c1-b9d324c6aacd required: true schema: type: string '/api/v1/c/{company_slug}/user/{user_uuid}/profile/picture': post: summary: 'Update User Profile Picture' operationId: updateUserProfilePicture description: "Upload or replace a user's profile picture." parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: uuid: b11fab33-a56a-4a78-a3c1-b9d324c6aacd createdAt: '2025-11-12T20:27:08+00:00' updatedAt: '2026-02-10T15:20:26+00:00' defaultCompanySlug: null emailVerifiedAt: null defaultCountryIsoCode: '' defaultCountryEmoji: '' email: liquid.ideas@gmail.com firstName: Jo lastName: Whitehouse phoneNumbers: [] roles: [] imgUrl: null imgThumbUrl: null imgLargeUrl: null imgUrlExpiresAt: null isActive: true disabledAt: null status: null statusName: null properties: data: type: object properties: uuid: type: string example: b11fab33-a56a-4a78-a3c1-b9d324c6aacd createdAt: type: string example: '2025-11-12T20:27:08+00:00' updatedAt: type: string example: '2026-02-10T15:20:26+00:00' defaultCompanySlug: type: string example: null nullable: true emailVerifiedAt: type: string example: null nullable: true defaultCountryIsoCode: type: string example: '' defaultCountryEmoji: type: string example: '' email: type: string example: liquid.ideas@gmail.com firstName: type: string example: Jo lastName: type: string example: Whitehouse phoneNumbers: type: array example: [] roles: type: array example: [] imgUrl: type: string example: null nullable: true imgThumbUrl: type: string example: null nullable: true imgLargeUrl: type: string example: null nullable: true imgUrlExpiresAt: type: string example: null nullable: true isActive: type: boolean example: true disabledAt: type: string example: null nullable: true status: type: string example: null nullable: true statusName: type: string example: null nullable: true tags: - 'Company User Management' requestBody: required: true content: multipart/form-data: schema: type: object properties: file: type: string format: binary description: 'The image file to upload. Must be an image (jpeg, png, etc).' required: - file parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: user_uuid description: '' example: b11fab33-a56a-4a78-a3c1-b9d324c6aacd required: true schema: type: string '/api/v1/c/{company_slug}/user/{user_uuid}/profile/picture/{format}': get: summary: 'Get User Profile Picture' operationId: getUserProfilePicture description: "Retrieve a user's profile picture." parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - 'Company User Management' parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: user_uuid description: '' example: b11fab33-a56a-4a78-a3c1-b9d324c6aacd required: true schema: type: string - in: path name: format description: 'Optional parameter. The image format (original, thumbnail).' required: true schema: type: string examples: omitted: summary: 'When the value is omitted' value: '' present: summary: 'When the value is present' value: thumbnail - in: path name: user description: 'The user UUID.' example: 550e8400-e29b-41d4-a716-446655440000 required: true schema: type: string '/api/v1/c/{company_slug}/user/bulk': post: summary: 'Bulk Upload Users' operationId: bulkUploadUsers description: "Upload a CSV file to create multiple users at once.\nCSV must have headers: email,firstName,lastName,roleSlug,phoneNumber" parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: total: 10 created: 8 skipped: 1 errors: 1 results: - email: john@example.com status: created - email: existing@example.com status: skipped reason: 'User already exists' properties: data: type: object properties: total: type: integer example: 10 created: type: integer example: 8 skipped: type: integer example: 1 errors: type: integer example: 1 results: type: array example: - email: john@example.com status: created - email: existing@example.com status: skipped reason: 'User already exists' items: type: object properties: email: type: string example: john@example.com status: type: string example: created tags: - 'Company User Management' requestBody: required: true content: multipart/form-data: schema: type: object properties: file: type: string format: binary description: 'CSV file with user data. Max 2MB.' required: - file parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string /api/v1/type/document: get: summary: 'Get Document Types' operationId: getDocumentTypes description: 'Retrieve all available document types.' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: - slug: unknown name: unknown documentSectionTypeSlug: null documentFormatTypeSlug: null - slug: unknown name: unknown documentSectionTypeSlug: null documentFormatTypeSlug: null properties: data: type: array example: - slug: unknown name: unknown documentSectionTypeSlug: null documentFormatTypeSlug: null - slug: unknown name: unknown documentSectionTypeSlug: null documentFormatTypeSlug: null items: type: object properties: slug: type: string example: unknown name: type: string example: unknown documentSectionTypeSlug: type: string example: null nullable: true documentFormatTypeSlug: type: string example: null nullable: true tags: - 'Document Types' /api/v1/type/document/format: get: summary: 'Get Document Format Types' operationId: getDocumentFormatTypes description: 'Retrieve all available document format types.' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: - slug: unknown name: unknown description: '' - slug: unknown name: unknown description: '' properties: data: type: array example: - slug: unknown name: unknown description: '' - slug: unknown name: unknown description: '' items: type: object properties: slug: type: string example: unknown name: type: string example: unknown description: type: string example: '' tags: - 'Document Types' /api/v1/type/document/section: get: summary: 'Get Document Section Types' operationId: getDocumentSectionTypes description: 'Retrieve all available document section types.' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: - slug: unknown name: unknown description: '' - slug: unknown name: unknown description: '' properties: data: type: array example: - slug: unknown name: unknown description: '' - slug: unknown name: unknown description: '' items: type: object properties: slug: type: string example: unknown name: type: string example: unknown description: type: string example: '' tags: - 'Document Types' '/api/v1/open-documents/{openDocument_uuid}/{format}': get: summary: 'Get Public Document' operationId: getPublicDocument description: "Retrieve a publicly shared document using its UUID.\nThis endpoint is publicly accessible without authentication." parameters: [] responses: 200: description: '' content: text/plain: schema: type: string example: 'binary The document file' 404: description: '' content: application/json: schema: type: object example: message: 'Document not found' properties: message: type: string example: 'Document not found' tags: - Documents security: [] parameters: - in: path name: openDocument_uuid description: '' example: 4f1b6eb2-9e4a-3efc-a892-afec3de63f6e required: true schema: type: string - in: path name: format description: 'Optional parameter. optional The format to return the document in (pdf, jpg, png). If not provided, returns the original format.' required: true schema: type: string examples: omitted: summary: 'When the value is omitted' value: '' present: summary: 'When the value is present' value: pdf - in: path name: openDocument description: 'The UUID of the document.' example: 550e8400-e29b-41d4-a716-446655440000 required: true schema: type: string /api/v1/sanctum/csrf-cookie: get: summary: 'Return an empty response simply to trigger the storage of the CSRF cookie in the browser.' operationId: returnAnEmptyResponseSimplyToTriggerTheStorageOfTheCSRFCookieInTheBrowser description: '' parameters: [] responses: 204: description: '' content: text/plain: schema: type: string example: '' tags: - Endpoints /api/v1/broadcasting/auth: get: summary: 'Authenticate the request for channel access.' operationId: authenticateTheRequestForChannelAccess description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints '/api/v1/c/{company_slug}/automation-rules': get: summary: '' operationId: getApiV1CCompany_slugAutomationRules description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints post: summary: '' operationId: postApiV1CCompany_slugAutomationRules description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: companySlug: type: string description: 'Company scope slug. Provide exactly one scope field. The slug of an existing record in the companies table.' example: acme-solar nullable: true farmUuid: type: string description: 'Farm scope UUID. Provide exactly one scope field. Must be a valid UUID. The uuid of an existing record in the farms table.' example: 550e8400-e29b-41d4-a716-446655440101 nullable: true collectorUuid: type: string description: 'Collector scope UUID. Provide exactly one scope field. Must be a valid UUID. The uuid of an existing record in the collectors table.' example: 550e8400-e29b-41d4-a716-446655440102 nullable: true status: type: string description: 'Automation rule status slug. The slug of an existing record in the automation_rule_status_types table.' example: enabled name: type: string description: 'Automation rule name. Must not be greater than 255 characters.' example: 'High Wind Stow Rule' description: type: string description: 'Automation rule description.' example: 'Stows trackers when wind speed exceeds threshold.' nullable: true cooldownMinutes: type: integer description: 'Cooldown between rule triggers in minutes. Must be at least 0.' example: 15 nullable: true autoClear: type: boolean description: 'Whether the rule should auto-clear.' example: true nullable: true clearAfterSeconds: type: integer description: 'Seconds after which the rule auto-clears. Must be at least 0.' example: 300 nullable: true evaluationPeriodSeconds: type: integer description: 'Evaluation period in seconds. Must be at least 0.' example: 60 nullable: true evaluationCountThreshold: type: integer description: 'Number of breaches required in the evaluation period. Must be at least 0.' example: 3 nullable: true required: - status - name parameters: - in: path name: company_slug description: 'The slug of the company.' example: deserunt required: true schema: type: string '/api/v1/c/{company_slug}/automation-rules/{automationRule_uuid}': get: summary: '' operationId: getApiV1CCompany_slugAutomationRulesAutomationRule_uuid description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints put: summary: '' operationId: putApiV1CCompany_slugAutomationRulesAutomationRule_uuid description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: false content: application/json: schema: type: object properties: status: type: string description: 'Automation rule status slug. The slug of an existing record in the automation_rule_status_types table.' example: disabled nullable: true name: type: string description: 'Automation rule name. Must not be greater than 255 characters.' example: 'High Wind Stow Rule' nullable: true description: type: string description: 'Automation rule description.' example: 'Updated description for wind stow rule.' nullable: true cooldownMinutes: type: integer description: 'Cooldown between rule triggers in minutes. Must be at least 0.' example: 30 nullable: true autoClear: type: boolean description: 'Whether the rule should auto-clear.' example: true nullable: true clearAfterSeconds: type: integer description: 'Seconds after which the rule auto-clears. Must be at least 0.' example: 600 nullable: true evaluationPeriodSeconds: type: integer description: 'Evaluation period in seconds. Must be at least 0.' example: 120 nullable: true evaluationCountThreshold: type: integer description: 'Number of breaches required in the evaluation period. Must be at least 0.' example: 2 nullable: true delete: summary: '' operationId: deleteApiV1CCompany_slugAutomationRulesAutomationRule_uuid description: '' parameters: [] responses: { } tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: automationRule_uuid description: '' example: 47502e2b-4ffe-3a10-b16d-d676f89f6c53 required: true schema: type: string '/api/v1/c/{company_slug}/automation-webhook-sources': get: summary: '' operationId: getApiV1CCompany_slugAutomationWebhookSources description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints post: summary: '' operationId: postApiV1CCompany_slugAutomationWebhookSources description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: name: type: string description: 'Human-readable name for the inbound webhook source. Must not be greater than 255 characters.' example: 'Farm Weather Provider' farmUuid: type: string description: 'Optional farm UUID to scope this source to one farm. Must be a valid UUID. The uuid of an existing record in the farms table.' example: 550e8400-e29b-41d4-a716-446655440020 nullable: true required: - name parameters: - in: path name: company_slug description: 'The slug of the company.' example: amet required: true schema: type: string '/api/v1/c/{company_slug}/automation-webhook-sources/{automationInboundWebhookSource_uuid}': get: summary: '' operationId: getApiV1CCompany_slugAutomationWebhookSourcesAutomationInboundWebhookSource_uuid description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints delete: summary: '' operationId: deleteApiV1CCompany_slugAutomationWebhookSourcesAutomationInboundWebhookSource_uuid description: '' parameters: [] responses: { } tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: automationInboundWebhookSource_uuid description: '' example: 2c5ccbd0-ef65-3704-bff1-da1fa4e32bff required: true schema: type: string '/api/v1/c/{company_slug}/automation-webhook-sources/{automationInboundWebhookSource_uuid}/rotate': post: summary: '' operationId: postApiV1CCompany_slugAutomationWebhookSourcesAutomationInboundWebhookSource_uuidRotate description: '' parameters: [] responses: { } tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: automationInboundWebhookSource_uuid description: '' example: cebc0336-1d25-3643-a38c-5b4d9a1f73d3 required: true schema: type: string '/api/v1/c/{company_slug}/automation-events': get: summary: '' operationId: getApiV1CCompany_slugAutomationEvents description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: pariatur required: true schema: type: string '/api/v1/c/{company_slug}/automation-events/{automationEvent_uuid}': get: summary: '' operationId: getApiV1CCompany_slugAutomationEventsAutomationEvent_uuid description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: automationEvent_uuid description: '' example: 02ccea26-141c-4f51-9aea-470b69cea45c required: true schema: type: string '/api/v1/c/{company_slug}/automation-events/manual': post: summary: '' operationId: postApiV1CCompany_slugAutomationEventsManual description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: name: type: string description: 'The name of the manual event to fire. Must not be greater than 255 characters.' example: emergency_stow payload: type: object description: 'Optional payload data for the event.' example: reason: high_wind speed: 75 properties: { } nullable: true collectorUuid: type: string description: 'Optional collector UUID to scope the event. Must be a valid UUID.' example: 550e8400-e29b-41d4-a716-446655440001 nullable: true farmUuid: type: string description: 'Optional farm UUID to scope the event. Must be a valid UUID.' example: 550e8400-e29b-41d4-a716-446655440002 nullable: true required: - name parameters: - in: path name: company_slug description: 'The slug of the company.' example: facilis required: true schema: type: string '/api/v1/c/{company_slug}/automation-executions': get: summary: '' operationId: getApiV1CCompany_slugAutomationExecutions description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: beatae required: true schema: type: string '/api/v1/c/{company_slug}/automation-executions/{automationExecution_uuid}': get: summary: '' operationId: getApiV1CCompany_slugAutomationExecutionsAutomationExecution_uuid description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: automationExecution_uuid description: '' example: caca757f-1886-3529-892c-fa225b06d760 required: true schema: type: string '/api/v1/c/{company_slug}/automation/test/fire-event': post: summary: '' operationId: postApiV1CCompany_slugAutomationTestFireEvent description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: name: type: string description: 'Automation event name to fire. Must not be greater than 255 characters.' example: manual_stow_triggered payload: type: object description: 'Optional payload delivered with the event.' example: reason: high_wind windSpeed: 21.6 properties: { } nullable: true farmUuid: type: string description: 'Optional farm UUID to scope the event. Must be a valid UUID.' example: 550e8400-e29b-41d4-a716-446655440040 nullable: true collectorUuid: type: string description: 'Optional collector UUID to scope the event. Must be a valid UUID.' example: 550e8400-e29b-41d4-a716-446655440041 nullable: true required: - name parameters: - in: path name: company_slug description: 'The slug of the company.' example: molestiae required: true schema: type: string '/api/v1/c/{company_slug}/automation/test/dry-run-match': post: summary: '' operationId: postApiV1CCompany_slugAutomationTestDryRunMatch description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: ruleUuid: type: string description: 'UUID of the automation rule to evaluate. Must be a valid UUID. The uuid of an existing record in the automation_rules table.' example: 550e8400-e29b-41d4-a716-446655440030 eventPayload: type: object description: 'Event payload to run against rule conditions without executing actions.' example: eventName: wind_alert speed: 72.4 unit: kmh properties: { } required: - ruleUuid - eventPayload parameters: - in: path name: company_slug description: 'The slug of the company.' example: mollitia required: true schema: type: string '/api/v1/c/{company_slug}/automation/test/preview-template': post: summary: '' operationId: postApiV1CCompany_slugAutomationTestPreviewTemplate description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: template: type: string description: 'Template string to preview.' example: 'Alert: @{{ collector.name }} exceeded @{{ threshold }}.' context: type: object description: 'Template context data used for placeholder replacement.' example: collector: name: NCU-12 threshold: 85 properties: { } required: - template - context parameters: - in: path name: company_slug description: 'The slug of the company.' example: ea required: true schema: type: string '/api/v1/c/{company_slug}/automation/test/send-notification': post: summary: '' operationId: postApiV1CCompany_slugAutomationTestSendNotification description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: notificationPolicyUuid: type: string description: 'UUID of the notification policy used for this test send. Must be a valid UUID. The uuid of an existing record in the notification_policies table.' example: 550e8400-e29b-41d4-a716-446655440050 recipientEmail: type: string description: 'Recipient email address for the test notification. Must be a valid email address.' example: alerts@example.com context: type: object description: 'Optional context payload rendered in the notification template.' example: collectorName: NCU-5 alarm: overheat properties: { } nullable: true required: - notificationPolicyUuid - recipientEmail parameters: - in: path name: company_slug description: 'The slug of the company.' example: sed required: true schema: type: string '/api/v1/c/{company_slug}/automation/test/webhook-endpoints': get: summary: '' operationId: getApiV1CCompany_slugAutomationTestWebhookEndpoints description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints post: summary: '' operationId: postApiV1CCompany_slugAutomationTestWebhookEndpoints description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: name: type: string description: 'Unique endpoint name within the company. Must not be greater than 255 characters.' example: weather-station-test-endpoint required: - name parameters: - in: path name: company_slug description: 'The slug of the company.' example: laboriosam required: true schema: type: string '/api/v1/c/{company_slug}/automation/test/webhook-endpoints/{automationTestWebhookEndpoint_uuid}': get: summary: '' operationId: getApiV1CCompany_slugAutomationTestWebhookEndpointsAutomationTestWebhookEndpoint_uuid description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints put: summary: '' operationId: putApiV1CCompany_slugAutomationTestWebhookEndpointsAutomationTestWebhookEndpoint_uuid description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: enabled: type: boolean description: 'Whether this test webhook endpoint is enabled.' example: true required: - enabled delete: summary: '' operationId: deleteApiV1CCompany_slugAutomationTestWebhookEndpointsAutomationTestWebhookEndpoint_uuid description: '' parameters: [] responses: { } tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: automationTestWebhookEndpoint_uuid description: '' example: 1af33b09-003c-3eab-ba81-018126292856 required: true schema: type: string '/api/v1/c/{company_slug}/automation/test/webhook-endpoints/{automationTestWebhookEndpoint_uuid}/rotate': post: summary: '' operationId: postApiV1CCompany_slugAutomationTestWebhookEndpointsAutomationTestWebhookEndpoint_uuidRotate description: '' parameters: [] responses: { } tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: automationTestWebhookEndpoint_uuid description: '' example: 914e15d4-6c65-3d69-a161-cc140c8d0332 required: true schema: type: string '/api/v1/c/{company_slug}/automation/test/webhook-endpoints/{automationTestWebhookEndpoint_uuid}/events': get: summary: '' operationId: getApiV1CCompany_slugAutomationTestWebhookEndpointsAutomationTestWebhookEndpoint_uuidEvents description: '' parameters: - in: query name: perPage description: 'Number of events to return per page. Must be at least 1. Must not be greater than 100.' example: 25 required: false schema: type: integer description: 'Number of events to return per page. Must be at least 1. Must not be greater than 100.' example: 25 nullable: true - in: query name: page description: 'Pagination page number. Must be at least 1.' example: 1 required: false schema: type: integer description: 'Pagination page number. Must be at least 1.' example: 1 nullable: true responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints delete: summary: '' operationId: deleteApiV1CCompany_slugAutomationTestWebhookEndpointsAutomationTestWebhookEndpoint_uuidEvents description: '' parameters: [] responses: { } tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: automationTestWebhookEndpoint_uuid description: '' example: 8f09bdbc-ea8e-3276-a213-88db58ad1169 required: true schema: type: string '/api/v1/c/{company_slug}/automation/test/webhook-endpoints/{automationTestWebhookEndpoint_uuid}/events/latest': get: summary: '' operationId: getApiV1CCompany_slugAutomationTestWebhookEndpointsAutomationTestWebhookEndpoint_uuidEventsLatest description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: automationTestWebhookEndpoint_uuid description: '' example: 3fdd9be7-0482-36cf-a114-9c3119a30f1c required: true schema: type: string '/api/v1/c/{company_slug}/automation/test/webhook-events/{automationTestWebhookEvent_uuid}': get: summary: '' operationId: getApiV1CCompany_slugAutomationTestWebhookEventsAutomationTestWebhookEvent_uuid description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints delete: summary: '' operationId: deleteApiV1CCompany_slugAutomationTestWebhookEventsAutomationTestWebhookEvent_uuid description: '' parameters: [] responses: { } tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: automationTestWebhookEvent_uuid description: '' example: 91e705ae-f385-375a-a367-24f678ab3937 required: true schema: type: string '/api/v1/c/{company_slug}/automation/test/webhook-inbox/setup': post: summary: '' operationId: postApiV1CCompany_slugAutomationTestWebhookInboxSetup description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: false content: application/json: schema: type: object properties: name: type: string description: 'Optional display name for the webhook inbox endpoint. Must not be greater than 255 characters.' example: 'Automation Test Inbox' nullable: true resetEvents: type: boolean description: 'Whether to clear existing captured webhook events before setup.' example: false nullable: true rotateSecret: type: boolean description: 'Whether to rotate the endpoint secret during setup.' example: true nullable: true notificationChannelUuid: type: string description: 'Optional notification channel UUID to connect with this inbox. Must be a valid UUID. The uuid of an existing record in the notification_channels table.' example: 550e8400-e29b-41d4-a716-446655440010 nullable: true parameters: - in: path name: company_slug description: 'The slug of the company.' example: vero required: true schema: type: string '/api/v1/c/{company_slug}/collector/{collector_uuid}/failures': get: summary: 'List failure logs for a collector.' operationId: listFailureLogsForACollector description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints post: summary: 'Report a new failure for a collector.' operationId: reportANewFailureForACollector description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: failureTypeSlug: type: string description: 'The slug of the failure type.' example: hardware_failure description: type: string description: 'Description of the failure.' example: 'Motor stuck' severity: type: string description: 'Severity level (low, medium, high, critical).' example: high detectedAt: type: string description: 'optional ISO 8601 datetime when failure was detected.' example: '2026-02-14T10:00:00Z' nullable: true required: - failureTypeSlug - description - severity parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: collector_uuid description: '' example: aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa required: true schema: type: string - in: path name: company description: 'The slug of the company' example: et required: true schema: type: string - in: path name: collector description: 'The UUID of the collector' example: esse required: true schema: type: string '/api/v1/c/{company_slug}/collector': post: summary: 'Create a new collector for the company' operationId: createANewCollectorForTheCompany description: '' parameters: [] responses: 201: description: '' content: application/json: schema: type: object example: data: uuid: 550e8400-e29b-41d4-a716-446655440000 name: 'Main Collector' description: 'Collector for north field' collectorTypeSlug: ncu type: NCU parentUuid: null childrenUuids: [] serial: COL-001-2024 location: lat: 51.509865 lng: -0.118092 currentJunction: uuid: 550e8400-e29b-41d4-a716-446655440002 farmSectionUuid: 550e8400-e29b-41d4-a716-446655440123 row: 0 column: 0 createdAt: '2024-01-20T12:00:00Z' updatedAt: '2024-01-20T12:00:00Z' properties: data: type: object properties: uuid: type: string example: 550e8400-e29b-41d4-a716-446655440000 name: type: string example: 'Main Collector' description: type: string example: 'Collector for north field' collectorTypeSlug: type: string example: ncu type: type: string example: NCU parentUuid: type: string example: null nullable: true childrenUuids: type: array example: [] serial: type: string example: COL-001-2024 location: type: object properties: lat: type: number example: 51.509865 lng: type: number example: -0.118092 currentJunction: type: object properties: uuid: type: string example: 550e8400-e29b-41d4-a716-446655440002 farmSectionUuid: type: string example: 550e8400-e29b-41d4-a716-446655440123 row: type: integer example: 0 column: type: integer example: 0 createdAt: type: string example: '2024-01-20T12:00:00Z' updatedAt: type: string example: '2024-01-20T12:00:00Z' 422: description: '' content: application/json: schema: type: object example: message: 'The given data was invalid.' errors: name: - 'The collector name field is required.' locationJson.latitude: - 'The latitude must be between -90 and 90 degrees' properties: message: type: string example: 'The given data was invalid.' errors: type: object properties: name: type: array example: - 'The collector name field is required.' items: type: string locationJson.latitude: type: array example: - 'The latitude must be between -90 and 90 degrees' items: type: string tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: name: type: string description: 'The name of the collector.' example: 'Main Collector' description: type: string description: 'optional The description of the collector.' example: 'Collector for north field' nullable: true locationJson: type: object description: 'Collector location (lat/lng).' example: latitude: 51.509865 longitude: -0.118092 properties: latitude: type: numeric description: 'optional The latitude coordinate between -90 and 90 (required when locationJson is provided).' example: '51.509865' longitude: type: numeric description: 'optional The longitude coordinate between -180 and 180 (required when locationJson is provided).' example: '-0.118092' nullable: true collectorTypeSlug: type: string description: 'The collector type slug (ncu or tcu).' example: ncu parentUuid: type: string description: 'optional The UUID of the parent NCU (required when collectorTypeSlug is tcu).' example: 550e8400-e29b-41d4-a716-446655440000 serial: type: string description: 'The serial number of the collector.' example: COL-001-2024 farmSectionUuid: type: string description: 'The UUID of the farm section to assign the collector to.' example: 550e8400-e29b-41d4-a716-446655440123 required: - name - collectorTypeSlug - serial - farmSectionUuid get: summary: 'Get All Collectors' operationId: getAllCollectors description: '' parameters: - in: query name: page description: 'Page number for pagination.' example: 1 required: false schema: type: integer description: 'Page number for pagination.' example: 1 - in: query name: perPage description: 'Number of items per page.' example: 15 required: false schema: type: integer description: 'Number of items per page.' example: 15 - in: query name: type description: 'Filter by collector type (ncu or tcu).' example: ncu required: false schema: type: string description: 'Filter by collector type (ncu or tcu).' example: ncu - in: query name: parent_uuid description: 'Filter TCUs by parent NCU UUID.' example: 550e8400-e29b-41d4-a716-446655440000 required: false schema: type: string description: 'Filter TCUs by parent NCU UUID.' example: 550e8400-e29b-41d4-a716-446655440000 - in: query name: format description: 'Response format (paginated or keyed). Default: paginated.' example: paginated required: false schema: type: string description: 'Response format (paginated or keyed). Default: paginated.' example: paginated responses: 200: description: '' content: application/json: schema: oneOf: - description: '' type: object example: data: - uuid: aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa createdAt: '2026-02-12T13:40:48+00:00' updatedAt: '2026-02-12T13:40:48+00:00' enabled: true companySlug: tracklab farmUuid: c9b4c54e-a135-4a7f-86c9-7f03b9329a1b collectorTypeSlug: ncu type: NCU parentUuid: null childrenUuids: [] serial: SYSTEM-HOLDING-NCU name: 'Unassigned Collectors' description: 'System-level holding NCU for auto-subscribed collectors awaiting assignment' location: null isDecommissioned: false decommissionedAt: null decommissionReason: null currentTracker: null status: null hardwareVersion: null currentFirmware: null manufacturedAt: null deployedAt: null retiredAt: null - uuid: aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa createdAt: '2026-02-12T13:40:48+00:00' updatedAt: '2026-02-12T13:40:48+00:00' enabled: true companySlug: tracklab farmUuid: c9b4c54e-a135-4a7f-86c9-7f03b9329a1b collectorTypeSlug: ncu type: NCU parentUuid: null childrenUuids: [] serial: SYSTEM-HOLDING-NCU name: 'Unassigned Collectors' description: 'System-level holding NCU for auto-subscribed collectors awaiting assignment' location: null isDecommissioned: false decommissionedAt: null decommissionReason: null currentTracker: null status: null hardwareVersion: null currentFirmware: null manufacturedAt: null deployedAt: null retiredAt: null properties: data: type: array example: - uuid: aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa createdAt: '2026-02-12T13:40:48+00:00' updatedAt: '2026-02-12T13:40:48+00:00' enabled: true companySlug: tracklab farmUuid: c9b4c54e-a135-4a7f-86c9-7f03b9329a1b collectorTypeSlug: ncu type: NCU parentUuid: null childrenUuids: [] serial: SYSTEM-HOLDING-NCU name: 'Unassigned Collectors' description: 'System-level holding NCU for auto-subscribed collectors awaiting assignment' location: null isDecommissioned: false decommissionedAt: null decommissionReason: null currentTracker: null status: null hardwareVersion: null currentFirmware: null manufacturedAt: null deployedAt: null retiredAt: null - uuid: aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa createdAt: '2026-02-12T13:40:48+00:00' updatedAt: '2026-02-12T13:40:48+00:00' enabled: true companySlug: tracklab farmUuid: c9b4c54e-a135-4a7f-86c9-7f03b9329a1b collectorTypeSlug: ncu type: NCU parentUuid: null childrenUuids: [] serial: SYSTEM-HOLDING-NCU name: 'Unassigned Collectors' description: 'System-level holding NCU for auto-subscribed collectors awaiting assignment' location: null isDecommissioned: false decommissionedAt: null decommissionReason: null currentTracker: null status: null hardwareVersion: null currentFirmware: null manufacturedAt: null deployedAt: null retiredAt: null items: type: object properties: uuid: type: string example: aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa description: 'The unique identifier of the collector' createdAt: type: string example: '2026-02-12T13:40:48+00:00' description: 'The creation timestamp (ISO8601)' updatedAt: type: string example: '2026-02-12T13:40:48+00:00' description: 'The last update timestamp (ISO8601)' enabled: type: boolean example: true description: 'Whether the collector is enabled' companySlug: type: string example: tracklab description: 'The slug of the company this collector belongs to' farmUuid: type: string example: c9b4c54e-a135-4a7f-86c9-7f03b9329a1b description: 'The UUID of the farm this collector belongs to' collectorTypeSlug: type: string example: ncu description: 'The slug of the collector type' type: type: string example: NCU description: 'The type of collector (NCU or TCU)' parentUuid: type: string example: null description: 'The UUID of the parent collector (for TCUs)' childrenUuids: type: array example: [] description: 'Array of child collector UUIDs (for NCUs)' serial: type: string example: SYSTEM-HOLDING-NCU description: 'The serial number of the collector' name: type: string example: 'Unassigned Collectors' description: 'The name of the collector' description: type: string example: 'System-level holding NCU for auto-subscribed collectors awaiting assignment' description: 'The description of the collector' location: type: string example: null description: 'The location coordinates' isDecommissioned: type: boolean example: false description: 'Whether the collector is decommissioned' decommissionedAt: type: string example: null description: 'The decommission timestamp (ISO8601)' decommissionReason: type: string example: null description: 'The reason for decommission' currentTracker: type: string example: null description: 'The current tracker placement' status: type: string example: null description: 'The current lifecycle status' hardwareVersion: type: string example: null description: 'The hardware version type' currentFirmware: type: string example: null description: 'The current firmware information' manufacturedAt: type: string example: null description: 'The manufacture timestamp (ISO8601)' deployedAt: type: string example: null description: 'The deployment timestamp (ISO8601)' retiredAt: type: string example: null description: 'The retirement timestamp (ISO8601)' - description: '' type: object example: data: - uuid: 550e8400-e29b-41d4-a716-446655440000 name: 'Main Collector' description: 'Primary collector' type: NCU typeId: 1 parentUuid: null childrenUuids: - 550e8400-e29b-41d4-a716-446655440001 createdAt: '2024-01-20T12:00:00Z' updatedAt: '2024-01-20T12:00:00Z' enabled: true companySlug: tracklab farmUuid: c9b4c54e-a135-4a7f-86c9-7f03b9329a1b serial: NCU-001 location: lat: 51.509865 lng: -0.118092 links: first: 'http://example.com/api/company/tracklab/collector?page=1' last: 'http://example.com/api/company/tracklab/collector?page=5' prev: null next: 'http://example.com/api/company/tracklab/collector?page=2' meta: current_page: 1 from: 1 last_page: 5 path: 'http://example.com/api/company/tracklab/collector' perPage: 15 to: 15 total: 75 properties: data: type: array example: - uuid: 550e8400-e29b-41d4-a716-446655440000 name: 'Main Collector' description: 'Primary collector' type: NCU typeId: 1 parentUuid: null childrenUuids: - 550e8400-e29b-41d4-a716-446655440001 createdAt: '2024-01-20T12:00:00Z' updatedAt: '2024-01-20T12:00:00Z' enabled: true companySlug: tracklab farmUuid: c9b4c54e-a135-4a7f-86c9-7f03b9329a1b serial: NCU-001 location: lat: 51.509865 lng: -0.118092 items: type: object properties: uuid: type: string example: 550e8400-e29b-41d4-a716-446655440000 description: 'The unique identifier of the collector' name: type: string example: 'Main Collector' description: 'The name of the collector' description: type: string example: 'Primary collector' description: 'The description of the collector' type: type: string example: NCU description: 'The type of collector (NCU or TCU)' typeId: type: integer example: 1 parentUuid: type: string example: null description: 'The UUID of the parent collector (for TCUs)' childrenUuids: type: array example: - 550e8400-e29b-41d4-a716-446655440001 description: 'Array of child collector UUIDs (for NCUs)' items: type: string createdAt: type: string example: '2024-01-20T12:00:00Z' description: 'The creation timestamp (ISO8601)' updatedAt: type: string example: '2024-01-20T12:00:00Z' description: 'The last update timestamp (ISO8601)' enabled: type: boolean example: true description: 'Whether the collector is enabled' companySlug: type: string example: tracklab description: 'The slug of the company this collector belongs to' farmUuid: type: string example: c9b4c54e-a135-4a7f-86c9-7f03b9329a1b description: 'The UUID of the farm this collector belongs to' serial: type: string example: NCU-001 description: 'The serial number of the collector' location: type: object properties: lat: type: number example: 51.509865 description: 'The latitude coordinate' lng: type: number example: -0.118092 description: 'The longitude coordinate' description: 'The location coordinates' links: type: object properties: first: type: string example: 'http://example.com/api/company/tracklab/collector?page=1' last: type: string example: 'http://example.com/api/company/tracklab/collector?page=5' prev: type: string example: null nullable: true next: type: string example: 'http://example.com/api/company/tracklab/collector?page=2' meta: type: object properties: current_page: type: integer example: 1 from: type: integer example: 1 last_page: type: integer example: 5 path: type: string example: 'http://example.com/api/company/tracklab/collector' perPage: type: integer example: 15 to: type: integer example: 15 total: type: integer example: 75 tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: company description: 'The slug of the company' example: vel required: true schema: type: string '/api/v1/c/{company_slug}/collector/parameter': get: summary: 'Get All Collector Parameters' operationId: getAllCollectorParameters description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: company description: 'The slug of the company' example: aut required: true schema: type: string '/api/v1/c/{company_slug}/collector/measurement/available': get: summary: 'Get All Collector Measurement Availability' operationId: getAllCollectorMeasurementAvailability description: 'Returns measurement availability (min/max timestamps) for all collectors in the company.' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: '': '': collectorUuid: uuid-here collectorMeasurementTypeSlug: ncu-cpu-temperature minTimestamp: '2025-11-12T22:40:36Z' maxTimestamp: '2025-12-14T22:13:05Z' dataTypeSlug: numeric dataTypeName: Numeric dataTypeIsNumeric: true properties: data: type: object properties: '': type: object properties: '': type: object properties: collectorUuid: type: string example: uuid-here collectorMeasurementTypeSlug: type: string example: ncu-cpu-temperature minTimestamp: type: string example: '2025-11-12T22:40:36Z' maxTimestamp: type: string example: '2025-12-14T22:13:05Z' dataTypeSlug: type: string example: numeric dataTypeName: type: string example: Numeric dataTypeIsNumeric: type: boolean example: true tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: company description: 'The slug of the company' example: quia required: true schema: type: string '/api/v1/c/{company_slug}/collector/measurement/available/group': get: summary: 'Get Collector Measurement Availability Grouped' operationId: getCollectorMeasurementAvailabilityGrouped description: 'Returns measurement availability aggregated by measurement type across all collectors.' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: '': collectorMeasurementTypeSlug: ncu-cpu-temperature minTimestamp: '2025-11-12T22:40:36Z' maxTimestamp: '2025-12-14T22:13:05Z' properties: data: type: object properties: '': type: object properties: collectorMeasurementTypeSlug: type: string example: ncu-cpu-temperature minTimestamp: type: string example: '2025-11-12T22:40:36Z' maxTimestamp: type: string example: '2025-12-14T22:13:05Z' tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: company description: 'The slug of the company' example: commodi required: true schema: type: string '/api/v1/c/{company_slug}/collector/{collector_uuid}': put: summary: 'Update Collector' operationId: updateCollector description: "Update an existing collector's details." parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: uuid: aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa createdAt: '2026-02-12T13:40:48+00:00' updatedAt: '2026-02-12T13:40:48+00:00' enabled: true companySlug: tracklab farmUuid: c9b4c54e-a135-4a7f-86c9-7f03b9329a1b collectorTypeSlug: ncu type: NCU parentUuid: null childrenUuids: [] serial: SYSTEM-HOLDING-NCU name: 'Unassigned Collectors' description: 'System-level holding NCU for auto-subscribed collectors awaiting assignment' location: null isDecommissioned: false decommissionedAt: null decommissionReason: null currentTracker: null status: null hardwareVersion: null currentFirmware: null manufacturedAt: null deployedAt: null retiredAt: null properties: data: type: object properties: uuid: type: string example: aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa description: 'The unique identifier of the collector' createdAt: type: string example: '2026-02-12T13:40:48+00:00' description: 'The creation timestamp (ISO8601)' updatedAt: type: string example: '2026-02-12T13:40:48+00:00' description: 'The last update timestamp (ISO8601)' enabled: type: boolean example: true description: 'Whether the collector is enabled' companySlug: type: string example: tracklab description: 'The slug of the company this collector belongs to' farmUuid: type: string example: c9b4c54e-a135-4a7f-86c9-7f03b9329a1b description: 'The UUID of the farm this collector belongs to' collectorTypeSlug: type: string example: ncu description: 'The slug of the collector type' type: type: string example: NCU description: 'The type of collector (NCU or TCU)' parentUuid: type: string example: null description: 'The UUID of the parent collector (for TCUs)' childrenUuids: type: array example: [] description: 'Array of child collector UUIDs (for NCUs)' serial: type: string example: SYSTEM-HOLDING-NCU description: 'The serial number of the collector' name: type: string example: 'Unassigned Collectors' description: 'The name of the collector' description: type: string example: 'System-level holding NCU for auto-subscribed collectors awaiting assignment' description: 'The description of the collector' location: type: string example: null description: 'The location coordinates' isDecommissioned: type: boolean example: false description: 'Whether the collector is decommissioned' decommissionedAt: type: string example: null description: 'The decommission timestamp (ISO8601)' decommissionReason: type: string example: null description: 'The reason for decommission' currentTracker: type: string example: null description: 'The current tracker placement' status: type: string example: null description: 'The current lifecycle status' hardwareVersion: type: string example: null description: 'The hardware version type' currentFirmware: type: string example: null description: 'The current firmware information' manufacturedAt: type: string example: null description: 'The manufacture timestamp (ISO8601)' deployedAt: type: string example: null description: 'The deployment timestamp (ISO8601)' retiredAt: type: string example: null description: 'The retirement timestamp (ISO8601)' tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: name: type: string description: 'The name of the collector.' example: 'Updated Field Collector' description: type: string description: 'The description of the collector.' example: 'Updated collector description' nullable: true locationJson: type: object description: 'Collector location (lat/lng).' example: latitude: 51.509865 longitude: -0.118092 properties: latitude: type: numeric description: 'The latitude coordinate between -90 and 90.' example: '51.509865' longitude: type: numeric description: 'The longitude coordinate between -180 and 180.' example: '-0.118092' nullable: true parentUuid: type: string description: 'The UUID of the parent NCU (only for TCUs).' example: 550e8400-e29b-41d4-a716-446655440000 nullable: true required: - name get: summary: 'Get Collector Details' operationId: getCollectorDetails description: '' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: uuid: aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa createdAt: '2026-02-12T13:40:48+00:00' updatedAt: '2026-02-12T13:40:48+00:00' enabled: true companySlug: tracklab farmUuid: c9b4c54e-a135-4a7f-86c9-7f03b9329a1b collectorTypeSlug: ncu type: NCU parentUuid: null childrenUuids: [] serial: SYSTEM-HOLDING-NCU name: 'Unassigned Collectors' description: 'System-level holding NCU for auto-subscribed collectors awaiting assignment' location: null isDecommissioned: false decommissionedAt: null decommissionReason: null currentTracker: null status: null hardwareVersion: null currentFirmware: null manufacturedAt: null deployedAt: null retiredAt: null properties: data: type: object properties: uuid: type: string example: aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa description: 'The unique identifier of the collector' createdAt: type: string example: '2026-02-12T13:40:48+00:00' description: 'The creation timestamp (ISO8601)' updatedAt: type: string example: '2026-02-12T13:40:48+00:00' description: 'The last update timestamp (ISO8601)' enabled: type: boolean example: true description: 'Whether the collector is enabled' companySlug: type: string example: tracklab description: 'The slug of the company this collector belongs to' farmUuid: type: string example: c9b4c54e-a135-4a7f-86c9-7f03b9329a1b description: 'The UUID of the farm this collector belongs to' collectorTypeSlug: type: string example: ncu description: 'The slug of the collector type' type: type: string example: NCU description: 'The type of collector (NCU or TCU)' parentUuid: type: string example: null description: 'The UUID of the parent collector (for TCUs)' childrenUuids: type: array example: [] description: 'Array of child collector UUIDs (for NCUs)' serial: type: string example: SYSTEM-HOLDING-NCU description: 'The serial number of the collector' name: type: string example: 'Unassigned Collectors' description: 'The name of the collector' description: type: string example: 'System-level holding NCU for auto-subscribed collectors awaiting assignment' description: 'The description of the collector' location: type: string example: null description: 'The location coordinates' isDecommissioned: type: boolean example: false description: 'Whether the collector is decommissioned' decommissionedAt: type: string example: null description: 'The decommission timestamp (ISO8601)' decommissionReason: type: string example: null description: 'The reason for decommission' currentTracker: type: string example: null description: 'The current tracker placement' status: type: string example: null description: 'The current lifecycle status' hardwareVersion: type: string example: null description: 'The hardware version type' currentFirmware: type: string example: null description: 'The current firmware information' manufacturedAt: type: string example: null description: 'The manufacture timestamp (ISO8601)' deployedAt: type: string example: null description: 'The deployment timestamp (ISO8601)' retiredAt: type: string example: null description: 'The retirement timestamp (ISO8601)' tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: collector_uuid description: '' example: aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa required: true schema: type: string - in: path name: company description: 'The slug of the company' example: at required: true schema: type: string - in: path name: collector description: 'The UUID of the collector' example: ipsa required: true schema: type: string '/api/v1/c/{company_slug}/collector/{collector_uuid}/children': get: summary: 'Get Child Collectors' operationId: getChildCollectors description: 'Get all TCUs that belong to a specific NCU' parameters: - in: query name: page description: 'Page number for pagination.' example: 1 required: false schema: type: integer description: 'Page number for pagination.' example: 1 - in: query name: perPage description: 'Number of items per page.' example: 15 required: false schema: type: integer description: 'Number of items per page.' example: 15 - in: query name: format description: 'Response format (paginated or keyed). Default: paginated.' example: paginated required: false schema: type: string description: 'Response format (paginated or keyed). Default: paginated.' example: paginated responses: 200: description: '' content: application/json: schema: type: object example: data: - uuid: aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa createdAt: '2026-02-12T13:40:48+00:00' updatedAt: '2026-02-12T13:40:48+00:00' enabled: true companySlug: tracklab farmUuid: c9b4c54e-a135-4a7f-86c9-7f03b9329a1b collectorTypeSlug: ncu type: NCU parentUuid: null childrenUuids: [] serial: SYSTEM-HOLDING-NCU name: 'Unassigned Collectors' description: 'System-level holding NCU for auto-subscribed collectors awaiting assignment' location: null isDecommissioned: false decommissionedAt: null decommissionReason: null currentTracker: null status: null hardwareVersion: null currentFirmware: null manufacturedAt: null deployedAt: null retiredAt: null - uuid: aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa createdAt: '2026-02-12T13:40:48+00:00' updatedAt: '2026-02-12T13:40:48+00:00' enabled: true companySlug: tracklab farmUuid: c9b4c54e-a135-4a7f-86c9-7f03b9329a1b collectorTypeSlug: ncu type: NCU parentUuid: null childrenUuids: [] serial: SYSTEM-HOLDING-NCU name: 'Unassigned Collectors' description: 'System-level holding NCU for auto-subscribed collectors awaiting assignment' location: null isDecommissioned: false decommissionedAt: null decommissionReason: null currentTracker: null status: null hardwareVersion: null currentFirmware: null manufacturedAt: null deployedAt: null retiredAt: null properties: data: type: array example: - uuid: aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa createdAt: '2026-02-12T13:40:48+00:00' updatedAt: '2026-02-12T13:40:48+00:00' enabled: true companySlug: tracklab farmUuid: c9b4c54e-a135-4a7f-86c9-7f03b9329a1b collectorTypeSlug: ncu type: NCU parentUuid: null childrenUuids: [] serial: SYSTEM-HOLDING-NCU name: 'Unassigned Collectors' description: 'System-level holding NCU for auto-subscribed collectors awaiting assignment' location: null isDecommissioned: false decommissionedAt: null decommissionReason: null currentTracker: null status: null hardwareVersion: null currentFirmware: null manufacturedAt: null deployedAt: null retiredAt: null - uuid: aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa createdAt: '2026-02-12T13:40:48+00:00' updatedAt: '2026-02-12T13:40:48+00:00' enabled: true companySlug: tracklab farmUuid: c9b4c54e-a135-4a7f-86c9-7f03b9329a1b collectorTypeSlug: ncu type: NCU parentUuid: null childrenUuids: [] serial: SYSTEM-HOLDING-NCU name: 'Unassigned Collectors' description: 'System-level holding NCU for auto-subscribed collectors awaiting assignment' location: null isDecommissioned: false decommissionedAt: null decommissionReason: null currentTracker: null status: null hardwareVersion: null currentFirmware: null manufacturedAt: null deployedAt: null retiredAt: null items: type: object properties: uuid: type: string example: aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa description: 'The unique identifier of the collector' createdAt: type: string example: '2026-02-12T13:40:48+00:00' description: 'The creation timestamp (ISO8601)' updatedAt: type: string example: '2026-02-12T13:40:48+00:00' description: 'The last update timestamp (ISO8601)' enabled: type: boolean example: true description: 'Whether the collector is enabled' companySlug: type: string example: tracklab description: 'The slug of the company this collector belongs to' farmUuid: type: string example: c9b4c54e-a135-4a7f-86c9-7f03b9329a1b description: 'The UUID of the farm this collector belongs to' collectorTypeSlug: type: string example: ncu description: 'The slug of the collector type' type: type: string example: NCU description: 'The type of collector (NCU or TCU)' parentUuid: type: string example: null description: 'The UUID of the parent collector (for TCUs)' childrenUuids: type: array example: [] description: 'Array of child collector UUIDs (for NCUs)' serial: type: string example: SYSTEM-HOLDING-NCU description: 'The serial number of the collector' name: type: string example: 'Unassigned Collectors' description: 'The name of the collector' description: type: string example: 'System-level holding NCU for auto-subscribed collectors awaiting assignment' description: 'The description of the collector' location: type: string example: null description: 'The location coordinates' isDecommissioned: type: boolean example: false description: 'Whether the collector is decommissioned' decommissionedAt: type: string example: null description: 'The decommission timestamp (ISO8601)' decommissionReason: type: string example: null description: 'The reason for decommission' currentTracker: type: string example: null description: 'The current tracker placement' status: type: string example: null description: 'The current lifecycle status' hardwareVersion: type: string example: null description: 'The hardware version type' currentFirmware: type: string example: null description: 'The current firmware information' manufacturedAt: type: string example: null description: 'The manufacture timestamp (ISO8601)' deployedAt: type: string example: null description: 'The deployment timestamp (ISO8601)' retiredAt: type: string example: null description: 'The retirement timestamp (ISO8601)' 400: description: '' content: application/json: schema: type: object example: error: 'Only NCU collectors can have children' properties: error: type: string example: 'Only NCU collectors can have children' tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: collector_uuid description: '' example: aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa required: true schema: type: string - in: path name: company description: 'The slug of the company' example: et required: true schema: type: string - in: path name: collector description: 'The UUID of the parent NCU collector' example: aliquam required: true schema: type: string '/api/v1/c/{company_slug}/collector/{collector_uuid}/parent': patch: summary: 'Update Collector Parent' operationId: updateCollectorParent description: 'Update the parent NCU of a TCU collector' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: uuid: 550e8400-e29b-41d4-a716-446655440001 name: 'TCU 1' description: 'Tracking Control Unit 1' type: TCU typeId: 2 parentUuid: 550e8400-e29b-41d4-a716-446655440000 properties: data: type: object properties: uuid: type: string example: 550e8400-e29b-41d4-a716-446655440001 name: type: string example: 'TCU 1' description: type: string example: 'Tracking Control Unit 1' type: type: string example: TCU typeId: type: integer example: 2 parentUuid: type: string example: 550e8400-e29b-41d4-a716-446655440000 400: description: '' content: application/json: schema: type: object example: error: 'Only TCU collectors can have a parent' properties: error: type: string example: 'Only TCU collectors can have a parent' tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: parentUuid: type: string description: 'The UUID of the parent NCU collector.' example: 550e8400-e29b-41d4-a716-446655440000 required: - parentUuid parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: collector_uuid description: '' example: aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa required: true schema: type: string - in: path name: company description: 'The slug of the company' example: deserunt required: true schema: type: string - in: path name: collector description: 'The UUID of the TCU collector' example: sed required: true schema: type: string '/api/v1/c/{company_slug}/collector/{collector_uuid}/parameter': get: summary: 'Get Collector Parameters' operationId: getCollectorParameters description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: collector_uuid description: '' example: aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa required: true schema: type: string - in: path name: company description: 'The slug of the company' example: qui required: true schema: type: string - in: path name: collector description: 'The UUID of the collector' example: dolore required: true schema: type: string '/api/v1/c/{company_slug}/collector/{collector_uuid}/measurement/available': get: summary: 'Get Collector Measurement Availability' operationId: getCollectorMeasurementAvailability description: 'Returns measurement availability (min/max timestamps) for a single collector.' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: '': collectorUuid: uuid-here collectorMeasurementTypeSlug: ncu-cpu-temperature minTimestamp: '2025-11-12T22:40:36Z' maxTimestamp: '2025-12-14T22:13:05Z' dataTypeSlug: numeric dataTypeName: Numeric dataTypeIsNumeric: true properties: data: type: object properties: '': type: object properties: collectorUuid: type: string example: uuid-here collectorMeasurementTypeSlug: type: string example: ncu-cpu-temperature minTimestamp: type: string example: '2025-11-12T22:40:36Z' maxTimestamp: type: string example: '2025-12-14T22:13:05Z' dataTypeSlug: type: string example: numeric dataTypeName: type: string example: Numeric dataTypeIsNumeric: type: boolean example: true tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: collector_uuid description: '' example: aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa required: true schema: type: string - in: path name: company description: 'The slug of the company' example: sapiente required: true schema: type: string - in: path name: collector description: 'The UUID of the collector' example: fugiat required: true schema: type: string '/api/v1/c/{company_slug}/collector/{collector_uuid}/timeline': get: summary: 'Get Collector Lifecycle Timeline' operationId: getCollectorLifecycleTimeline description: "Returns a chronological timeline of lifecycle events for a collector,\nincluding status changes, farm placements, handovers, and firmware changes." parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: collector_uuid description: '' example: aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa required: true schema: type: string - in: path name: company description: 'The slug of the company' example: quia required: true schema: type: string - in: path name: collector description: 'The UUID of the collector' example: saepe required: true schema: type: string '/api/v1/c/{company_slug}/collector/{collector_uuid}/parameters': put: summary: 'Update Collector Parameters' operationId: updateCollectorParameters description: "Update one or more parameters for a specific collector. This will update the local parameter\nvalues and send commands to the device to apply the changes." parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: parameters: type: object description: 'Object containing parameter slugs as keys and their new values' example: [] properties: { } required: - parameters parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: collector_uuid description: '' example: aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa required: true schema: type: string - in: path name: company description: 'The slug of the company' example: ut required: true schema: type: string - in: path name: collector description: 'The UUID of the collector' example: quia required: true schema: type: string '/api/v1/c/{company_slug}/collector/{collector_uuid}/firmware-update': post: summary: 'Initiate Firmware Update' operationId: initiateFirmwareUpdate description: "Assign a firmware version to a collector, record the assignment in the firmware history,\nand send the update command to the device via MQTT." parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: firmwareTypeSlug: type: string description: 'The slug of the firmware type to assign.' example: firmware-v1.2.3 required: - firmwareTypeSlug parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: collector_uuid description: '' example: aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa required: true schema: type: string - in: path name: company description: 'The slug of the company' example: non required: true schema: type: string - in: path name: collector description: 'The UUID of the collector' example: laborum required: true schema: type: string '/api/v1/c/{company_slug}/collector/{collector_uuid}/broadcast-parameters': post: summary: 'Broadcast Parameter Update' operationId: broadcastParameterUpdate description: "Send a single MQTT broadcast command to all child TCUs of an NCU,\nwhile storing parameters locally per-child-TCU." parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: parameters: type: object description: 'Key-value pairs of parameter slugs and their values' example: [] properties: { } required: - parameters parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: collector_uuid description: '' example: aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa required: true schema: type: string - in: path name: company description: 'The slug of the company' example: commodi required: true schema: type: string - in: path name: collector description: 'The UUID of the NCU collector' example: aliquam required: true schema: type: string '/api/v1/c/{company_slug}/collector/{collector_uuid}/farm': patch: summary: 'Move Collector to Farm' operationId: moveCollectorToFarm description: "Move a collector to a different farm. This creates a new entry in the\ncollector_farm_junctions table and deactivates the previous junction." parameters: [] responses: 200: description: '' content: text/plain: schema: type: string example: "{\n \"message\": \"Collector successfully moved to farm\",\n \"data\": {\n \"collector\": { ... },\n \"newFarm\": { \"uuid\": \"...\", \"name\": \"...\" },\n \"tracker\": { ... }\n }\n}" 404: description: '' content: application/json: schema: type: object example: error: 'Target farm not found or does not belong to this company' properties: error: type: string example: 'Target farm not found or does not belong to this company' tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: farmSectionUuid: type: string description: 'The UUID of the target farm section.' example: 550e8400-e29b-41d4-a716-446655440001 row: type: integer description: 'optional The row position in the new farm.' example: 3 nullable: true column: type: integer description: 'optional The column position in the new farm.' example: 5 nullable: true widthM: type: numeric description: 'optional The collector width in meters.' example: '6.5' nullable: true heightM: type: numeric description: 'optional The collector height in meters.' example: '2.4' nullable: true angleDeg: type: numeric description: 'optional The placement angle in degrees.' example: '12.5' nullable: true copyCollectorLocation: type: boolean description: 'optional When true, copies the collector location into the new junction record.' example: false required: - farmSectionUuid parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: collector_uuid description: '' example: aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa required: true schema: type: string - in: path name: company description: 'The slug of the company' example: deserunt required: true schema: type: string - in: path name: collector description: 'The UUID of the collector' example: corporis required: true schema: type: string '/api/v1/c/{company_slug}/collector/{collector_uuid}/decommission': post: summary: 'Decommission a Collector' operationId: decommissionACollector description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: false content: application/json: schema: type: object properties: reason: type: string description: 'optional Reason for decommissioning.' example: 'End of life β€” hardware fault' nullable: true parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: collector_uuid description: '' example: aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa required: true schema: type: string - in: path name: company description: 'The slug of the company' example: quidem required: true schema: type: string - in: path name: collector description: 'The UUID of the collector' example: modi required: true schema: type: string '/api/v1/c/{company_slug}/collector/{collector_uuid}/recommission': post: summary: 'Recommission a Decommissioned Collector' operationId: recommissionADecommissionedCollector description: '' parameters: [] responses: { } tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: collector_uuid description: '' example: aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa required: true schema: type: string - in: path name: company description: 'The slug of the company' example: ut required: true schema: type: string - in: path name: collector description: 'The UUID of the collector' example: architecto required: true schema: type: string '/api/v1/c/{company_slug}/collector/{collector_uuid}/unassign': post: summary: 'Unassign a collector from its current farm.' operationId: unassignACollectorFromItsCurrentFarm description: "Moves the collector to the company's unassigned farm/section and transitions\nits lifecycle status to 'unassigned'. For TCU collectors, the parent link is\nset to the system Holding NCU. For NCU collectors, the parent link is removed." parameters: [] responses: { } tags: - Endpoints requestBody: required: false content: application/json: schema: type: object properties: reason: type: string description: 'optional Reason for unassigning.' example: 'Relocated to different site' nullable: true parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: collector_uuid description: '' example: aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa required: true schema: type: string - in: path name: company description: 'The slug of the company' example: aut required: true schema: type: string - in: path name: collector description: 'The UUID of the collector' example: dolorem required: true schema: type: string '/api/v1/c/{company_slug}/collector/{oldCollector_uuid}/handover': post: summary: 'Handover a collector to a replacement collector while preserving tracker identity.' operationId: handoverACollectorToAReplacementCollectorWhilePreservingTrackerIdentity description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: replacementCollectorUuid: type: string description: 'UUID of the collector that will replace the current collector at this tracker. Must be a valid UUID. The uuid of an existing record in the collectors table.' example: 550e8400-e29b-41d4-a716-446655440123 required: - replacementCollectorUuid parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: oldCollector_uuid description: '' example: aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa required: true schema: type: string '/api/v1/c/{company_slug}/collector/{collector_uuid}/swap': post: summary: 'Swap a deployed/active collector with a replacement at the same farm position.' operationId: swapADeployedactiveCollectorWithAReplacementAtTheSameFarmPosition description: "Unassigns the old collector from its farm position and places the replacement\ncollector at the same farm, section, row, and column. The old collector is\ntransitioned to 'unassigned' and the replacement is transitioned to 'deployed'." parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: replacementCollectorUuid: type: string description: 'UUID of the replacement collector.' example: 550e8400-e29b-41d4-a716-446655440123 required: - replacementCollectorUuid parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: collector_uuid description: '' example: aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa required: true schema: type: string - in: path name: company description: 'The slug of the company' example: et required: true schema: type: string - in: path name: collector description: 'The UUID of the collector to swap out' example: eum required: true schema: type: string '/api/v1/c/{company_slug}/collector/{collector_uuid}/firmware': get: summary: 'Get Current Collector Firmware' operationId: getCurrentCollectorFirmware description: 'Returns the currently assigned firmware for a collector.' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: collector_uuid description: '' example: aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa required: true schema: type: string - in: path name: company description: 'The slug of the company' example: corrupti required: true schema: type: string - in: path name: collector description: 'The UUID of the collector' example: assumenda required: true schema: type: string '/api/v1/c/{company_slug}/collector/{collector_uuid}/firmware/history': get: summary: 'Get Collector Firmware History' operationId: getCollectorFirmwareHistory description: 'Returns the history of firmware assignments for a collector.' parameters: - in: query name: page description: 'Page number for pagination.' example: 1 required: false schema: type: integer description: 'Page number for pagination.' example: 1 - in: query name: perPage description: 'Number of items per page.' example: 15 required: false schema: type: integer description: 'Number of items per page.' example: 15 responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: collector_uuid description: '' example: aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa required: true schema: type: string - in: path name: company description: 'The slug of the company' example: et required: true schema: type: string - in: path name: collector description: 'The UUID of the collector' example: hic required: true schema: type: string '/api/v1/c/{company_slug}/tracker/{tracker_uuid}/name': patch: summary: 'Rename a tracker and lock it from automatic collector-name propagation.' operationId: renameATrackerAndLockItFromAutomaticCollectorNamePropagation description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: name: type: string description: 'Tracker display name. Setting this locks the tracker name from collector rename propagation. Must not be greater than 255 characters.' example: 'North Row Tracker A2' required: - name parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: tracker_uuid description: '' example: a205ee53-a5ce-4ecf-8103-d1ace6488432 required: true schema: type: string '/api/v1/c/{company_slug}/collector/{collector_uuid}/warranty': get: summary: 'List all warranties for a collector.' operationId: listAllWarrantiesForACollector description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: collector_uuid description: '' example: aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa required: true schema: type: string '/api/v1/c/{company_slug}/collector/{collector_uuid}/warranty/claims': post: summary: "File a warranty claim against a collector's warranty." operationId: fileAWarrantyClaimAgainstACollectorsWarranty description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: collectorWarrantyUuid: type: string description: 'UUID of the collector warranty this claim belongs to. Must be a valid UUID. The uuid of an existing record in the collector_warranties table.' example: 550e8400-e29b-41d4-a716-446655440060 description: type: string description: 'Summary of the warranty issue being claimed. Must not be greater than 5000 characters.' example: 'Actuator failed during normal operation within warranty period.' coveredByWarranty: type: boolean description: 'Whether the claim is expected to be covered under warranty terms.' example: true cost: type: number description: 'Optional estimated or invoiced claim amount. Must be at least 0.' example: 249.99 nullable: true rmaRequestUuid: type: string description: 'Optional related RMA request UUID. Must be a valid UUID. The uuid of an existing record in the rma_requests table.' example: 550e8400-e29b-41d4-a716-446655440061 nullable: true required: - collectorWarrantyUuid - description - coveredByWarranty parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: collector_uuid description: '' example: aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa required: true schema: type: string '/api/v1/c/{company_slug}/links': get: summary: 'List Company Links (Granted)' operationId: listCompanyLinksGranted description: 'Returns all company links granted by this company.' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints post: summary: 'Create Company Link' operationId: createCompanyLink description: 'Creates a new company link with an invite for the receiving company.' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: remoteCompanySlug: type: string description: 'The slug of the remote company to link with. The slug of an existing record in the companies table.' example: acme-corp roles: type: object description: 'Role assignments for the link.' example: [] properties: companyWide: type: array description: '' example: - technician items: type: string enum: - admin - owner - user - manager - technician - viewer - external-supplier - external-support farms: type: array description: '' example: null items: type: object properties: farmUuid: type: string description: 'This field is required when roles.farms is present. The uuid of an existing record in the farms table.' example: f4314a78-8e41-368f-86ca-1d5b02d70f6a roles: type: array description: '' example: - external-support items: type: string enum: - admin - owner - user - manager - technician - viewer - external-supplier - external-support collectors: type: array description: '' example: null items: type: object properties: collectorUuid: type: string description: 'This field is required when roles.collectors is present. The uuid of an existing record in the collectors table.' example: 71a04715-da40-33ce-a232-189424d6d6f9 roles: type: array description: '' example: - external-supplier items: type: string enum: - admin - owner - user - manager - technician - viewer - external-supplier - external-support validUntil: type: string description: 'Optional expiration date for the link. Must be a valid date.' example: '2026-12-31' nullable: true required: - remoteCompanySlug - roles parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string '/api/v1/c/{company_slug}/links/received': get: summary: 'List Received Company Links' operationId: listReceivedCompanyLinks description: 'Returns all company links received by this company.' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string '/api/v1/c/{company_slug}/links/{uuid}': get: summary: 'Show Company Link' operationId: showCompanyLink description: 'Returns details of a specific company link.' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints patch: summary: 'Update Company Link' operationId: updateCompanyLink description: 'Updates a company link status (suspend/reactivate).' parameters: [] responses: { } tags: - Endpoints requestBody: required: false content: application/json: schema: type: object properties: status: type: string description: 'The new status for the link (active or suspended).' example: active enum: - active - suspended validUntil: type: string description: 'Optional expiration date for the link. Must be a valid date.' example: '2026-12-31' nullable: true delete: summary: 'Unlink (Terminate) Company Link' operationId: unlinkTerminateCompanyLink description: 'Terminates a company link. Either company can unlink.' parameters: [] responses: { } tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: uuid description: '' example: 43f95020-2337-35d1-9a5a-cbe1a3fd5d53 required: true schema: type: string '/api/v1/c/{company_slug}/links/{link_uuid}/roles': post: summary: 'Add Company-Wide Role' operationId: addCompanyWideRole description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: roleSlug: type: string description: 'The role slug to assign.' example: user enum: - admin - owner - user - manager - technician - viewer - external-supplier - external-support required: - roleSlug parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: link_uuid description: '' example: bbb6720c-0d9a-3404-9f69-e3ff1fb2eccc required: true schema: type: string '/api/v1/c/{company_slug}/links/{link_uuid}/roles/{id}': delete: summary: 'Remove Company-Wide Role' operationId: removeCompanyWideRole description: '' parameters: [] responses: { } tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: link_uuid description: '' example: a33b1796-955d-33f0-86fe-ac3fedc10039 required: true schema: type: string - in: path name: id description: 'The ID of the role.' example: molestias required: true schema: type: string '/api/v1/c/{company_slug}/links/{link_uuid}/farms/{farm_uuid}/roles': post: summary: 'Add Farm-Level Role' operationId: addFarmLevelRole description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: roleSlug: type: string description: 'The role slug to assign.' example: user enum: - admin - owner - user - manager - technician - viewer - external-supplier - external-support required: - roleSlug parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: link_uuid description: '' example: efdbf07f-6a4f-3ea8-a244-3206f5af660f required: true schema: type: string - in: path name: farm_uuid description: '' example: c9b4c54e-a135-4a7f-86c9-7f03b9329a1b required: true schema: type: string '/api/v1/c/{company_slug}/links/{link_uuid}/farms/{farm_uuid}/roles/{id}': delete: summary: 'Remove Farm-Level Role' operationId: removeFarmLevelRole description: '' parameters: [] responses: { } tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: link_uuid description: '' example: 1685528d-c320-3bc3-8647-feef069fa3bb required: true schema: type: string - in: path name: farm_uuid description: '' example: c9b4c54e-a135-4a7f-86c9-7f03b9329a1b required: true schema: type: string - in: path name: id description: 'The ID of the role.' example: sit required: true schema: type: string '/api/v1/c/{company_slug}/links/{link_uuid}/collectors/{collector_uuid}/roles': post: summary: 'Add Collector-Specific Role' operationId: addCollectorSpecificRole description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: roleSlug: type: string description: 'The role slug to assign.' example: user enum: - admin - owner - user - manager - technician - viewer - external-supplier - external-support required: - roleSlug parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: link_uuid description: '' example: 720d5e90-e94d-38f3-b93c-fe1ca030800c required: true schema: type: string - in: path name: collector_uuid description: '' example: aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa required: true schema: type: string '/api/v1/c/{company_slug}/links/{link_uuid}/collectors/{collector_uuid}/roles/{id}': delete: summary: 'Remove Collector-Specific Role' operationId: removeCollectorSpecificRole description: '' parameters: [] responses: { } tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: link_uuid description: '' example: 113df914-a49c-3aef-979f-dfc9fbc03a77 required: true schema: type: string - in: path name: collector_uuid description: '' example: aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa required: true schema: type: string - in: path name: id description: 'The ID of the role.' example: vitae required: true schema: type: string '/api/v1/c/{company_slug}/link-invites': get: summary: 'List Pending Invites' operationId: listPendingInvites description: 'Returns all pending company link invites for this company (as receiving company).' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string '/api/v1/c/{company_slug}/link-invites/{invite_uuid}/accept': post: summary: 'Accept Company Link Invite' operationId: acceptCompanyLinkInvite description: 'Accepts a pending company link invite, activating the link.' parameters: [] responses: { } tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: invite_uuid description: '' example: 04300bc1-44ad-3550-9db5-190033241964 required: true schema: type: string '/api/v1/c/{company_slug}/link-invites/{invite_uuid}/reject': post: summary: 'Reject Company Link Invite' operationId: rejectCompanyLinkInvite description: 'Rejects a pending company link invite.' parameters: [] responses: { } tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: invite_uuid description: '' example: 4e2cb1d1-f210-3a52-be64-eb97885b73ab required: true schema: type: string '/api/v1/c/{company_slug}/device-groups': get: summary: '' operationId: getApiV1CCompany_slugDeviceGroups description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints post: summary: '' operationId: postApiV1CCompany_slugDeviceGroups description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: name: type: string description: 'Device group name (unique per company). Must not be greater than 255 characters.' example: 'Section A Collectors' description: type: string description: 'Description of the device group.' example: 'All collectors in section A of the farm' nullable: true targetFilters: type: object description: 'Filters to auto-select collectors.' example: deviceModelTypeSlugs: - ncu-v2 - tcu-v1 farmUuids: - 550e8400-e29b-41d4-a716-446655440000 properties: deviceModelTypeSlugs: type: array description: 'The slug of an existing record in the device_model_types table.' example: - ncu-v2 - tcu-v1 items: type: string farmUuids: type: array description: 'Must be a valid UUID. The uuid of an existing record in the farms table.' example: - 550e8400-e29b-41d4-a716-446655440000 items: type: string siteUuids: type: array description: 'Must be a valid UUID. The uuid of an existing record in the sites table.' example: - 984b3865-4d54-3e6e-9c31-ae1cfdcf39f7 items: type: string collectorUuids: type: array description: 'Must be a valid UUID. The uuid of an existing record in the collectors table.' example: - a921fdb8-b8db-3a7e-bad4-6423c5427596 items: type: string excludeCollectorUuids: type: array description: 'Must be a valid UUID. The uuid of an existing record in the collectors table.' example: - 2bf97750-942b-31ad-a619-c5b456543129 items: type: string nullable: true collectorUuids: type: array description: 'Must be a valid UUID. The uuid of an existing record in the collectors table.' example: - 288f43cb-6d11-3094-ad33-6c065b233e8f items: type: string required: - name parameters: - in: path name: company_slug description: 'The slug of the company.' example: rerum required: true schema: type: string '/api/v1/c/{company_slug}/device-groups/{deviceGroup_uuid}': get: summary: '' operationId: getApiV1CCompany_slugDeviceGroupsDeviceGroup_uuid description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints put: summary: '' operationId: putApiV1CCompany_slugDeviceGroupsDeviceGroup_uuid description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: false content: application/json: schema: type: object properties: name: type: string description: 'Device group name (unique per company). Must not be greater than 255 characters.' example: 'Section A Collectors Updated' description: type: string description: 'Description of the device group.' example: 'Updated collectors in section A' nullable: true targetFilters: type: object description: 'Filters to auto-select collectors.' example: deviceModelTypeSlugs: - ncu-v2 - tcu-v1 - ncu-v3 farmUuids: - 550e8400-e29b-41d4-a716-446655440000 - 550e8400-e29b-41d4-a716-446655440001 properties: deviceModelTypeSlugs: type: array description: 'The slug of an existing record in the device_model_types table.' example: - ncu-v2 - tcu-v1 - ncu-v3 items: type: string farmUuids: type: array description: 'Must be a valid UUID. The uuid of an existing record in the farms table.' example: - 550e8400-e29b-41d4-a716-446655440000 - 550e8400-e29b-41d4-a716-446655440001 items: type: string siteUuids: type: array description: 'Must be a valid UUID. The uuid of an existing record in the sites table.' example: - cbce6330-3a7d-331a-8ad9-322dea2ffb6c items: type: string collectorUuids: type: array description: 'Must be a valid UUID. The uuid of an existing record in the collectors table.' example: - 351d3c86-082f-3c98-8775-8bc174d5a208 items: type: string excludeCollectorUuids: type: array description: 'Must be a valid UUID. The uuid of an existing record in the collectors table.' example: - 16dc09f0-9863-388c-89ea-d5c5ebd6d3f2 items: type: string nullable: true collectorUuids: type: array description: 'Must be a valid UUID. The uuid of an existing record in the collectors table.' example: - f49077c5-5af9-3159-b80e-b4dd07ab3710 items: type: string delete: summary: '' operationId: deleteApiV1CCompany_slugDeviceGroupsDeviceGroup_uuid description: '' parameters: [] responses: { } tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: deviceGroup_uuid description: '' example: a2f63e5f-8488-4b5f-a10e-04616e26f78d required: true schema: type: string '/api/v1/c/{company_slug}/device-groups/{deviceGroup_uuid}/collectors': post: summary: '' operationId: postApiV1CCompany_slugDeviceGroupsDeviceGroup_uuidCollectors description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: action: type: string description: 'Action to perform: add or remove collectors.' example: add enum: - add - remove collectorUuids: type: array description: 'Must be a valid UUID. The uuid of an existing record in the collectors table.' example: - c251451e-23b1-36ea-a18a-fe9fb2f4ced4 items: type: string required: - action parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: deviceGroup_uuid description: '' example: a2f63e5f-8488-4b5f-a10e-04616e26f78d required: true schema: type: string '/api/v1/c/{company_slug}/device-models': get: summary: '' operationId: getApiV1CCompany_slugDeviceModels description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints post: summary: '' operationId: postApiV1CCompany_slugDeviceModels description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: name: type: string description: 'Name of the device model type. Must not be greater than 255 characters.' example: 'NCU v2.0' slug: type: string description: 'URL-friendly identifier (auto-generated if not provided). Must not be greater than 255 characters.' example: ncu-v2 nullable: true description: type: string description: 'Description of the device model type.' example: 'Network Control Unit version 2.0 with enhanced capabilities' nullable: true manufacturer: type: string description: 'Manufacturer name. Must not be greater than 255 characters.' example: TrackLab nullable: true collectorTypeSlug: type: string description: 'Slug of the associated collector type. The slug of an existing record in the collector_types table.' example: ncu nullable: true hardwareVersions: type: array description: 'Must not be greater than 50 characters.' example: - fsxglmdifknysknnikzrqlhfq items: type: string capabilities: type: array description: '' example: null items: type: string nullable: true enabled: type: boolean description: 'Whether the device model type is enabled.' example: true orderColumn: type: integer description: 'Display order. Must be at least 0.' example: 1 required: - name parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string '/api/v1/c/{company_slug}/device-models/{deviceModelType_slug}': get: summary: '' operationId: getApiV1CCompany_slugDeviceModelsDeviceModelType_slug description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints put: summary: '' operationId: putApiV1CCompany_slugDeviceModelsDeviceModelType_slug description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: false content: application/json: schema: type: object properties: name: type: string description: 'Name of the device model type. Must not be greater than 255 characters.' example: 'NCU v2.0' slug: type: string description: 'URL-friendly identifier. Must not be greater than 255 characters.' example: ncu-v2 description: type: string description: 'Description of the device model type.' example: 'Network Control Unit version 2.0 with enhanced capabilities' manufacturer: type: string description: 'Manufacturer name. Must not be greater than 255 characters.' example: TrackLab collectorTypeSlug: type: string description: 'Slug of the associated collector type. The slug of an existing record in the collector_types table.' example: ncu nullable: true hardwareVersions: type: array description: 'Must not be greater than 50 characters.' example: - lwos items: type: string capabilities: type: array description: '' example: null items: type: string nullable: true enabled: type: boolean description: 'Whether the device model type is enabled.' example: true orderColumn: type: integer description: 'Display order. Must be at least 0.' example: 1 delete: summary: '' operationId: deleteApiV1CCompany_slugDeviceModelsDeviceModelType_slug description: '' parameters: [] responses: { } tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: deviceModelType_slug description: 'The slug of the deviceModelType.' example: unknown required: true schema: type: string '/api/v1/c/{company_slug}/device-models/{deviceModelType_slug}/toggle': put: summary: '' operationId: putApiV1CCompany_slugDeviceModelsDeviceModelType_slugToggle description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: enabled: type: boolean description: '' example: false required: - enabled parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: deviceModelType_slug description: 'The slug of the deviceModelType.' example: unknown required: true schema: type: string '/api/v1/c/{company_slug}/farm': get: summary: 'Get All Farms' operationId: getAllFarms description: 'Retrieve all farms associated with the company.' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: - uuid: c9b4c54e-a135-4a7f-86c9-7f03b9329a1b createdAt: '2024-01-03T20:11:13+00:00' updatedAt: '2024-01-03T20:11:13+00:00' enabled: true companySlug: tracklab name: 'First Farm' description: '' location: lat: -25.91 lng: 28.12 isUnassigned: false - uuid: c9b4c54e-a135-4a7f-86c9-7f03b9329a1b createdAt: '2024-01-03T20:11:13+00:00' updatedAt: '2024-01-03T20:11:13+00:00' enabled: true companySlug: tracklab name: 'First Farm' description: '' location: lat: -25.91 lng: 28.12 isUnassigned: false properties: data: type: array example: - uuid: c9b4c54e-a135-4a7f-86c9-7f03b9329a1b createdAt: '2024-01-03T20:11:13+00:00' updatedAt: '2024-01-03T20:11:13+00:00' enabled: true companySlug: tracklab name: 'First Farm' description: '' location: lat: -25.91 lng: 28.12 isUnassigned: false - uuid: c9b4c54e-a135-4a7f-86c9-7f03b9329a1b createdAt: '2024-01-03T20:11:13+00:00' updatedAt: '2024-01-03T20:11:13+00:00' enabled: true companySlug: tracklab name: 'First Farm' description: '' location: lat: -25.91 lng: 28.12 isUnassigned: false items: type: object properties: uuid: type: string example: c9b4c54e-a135-4a7f-86c9-7f03b9329a1b description: 'The unique identifier of the farm' createdAt: type: string example: '2024-01-03T20:11:13+00:00' description: 'The timestamp when the farm was created' updatedAt: type: string example: '2024-01-03T20:11:13+00:00' description: 'The timestamp when the farm was last updated' enabled: type: boolean example: true description: 'Whether the farm is enabled' companySlug: type: string example: tracklab description: 'The slug of the company this farm belongs to' name: type: string example: 'First Farm' description: 'The name of the farm' description: type: string example: '' description: 'The description of the farm' location: type: object properties: lat: type: number example: -25.91 description: 'The latitude coordinate' lng: type: number example: 28.12 description: 'The longitude coordinate' description: 'The location coordinates' isUnassigned: type: boolean example: false tags: - Endpoints post: summary: 'Add New Farm' operationId: addNewFarm description: 'Create a new farm for the company.' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: uuid: c9b4c54e-a135-4a7f-86c9-7f03b9329a1b createdAt: '2024-01-03T20:11:13+00:00' updatedAt: '2024-01-03T20:11:13+00:00' enabled: true companySlug: tracklab name: 'First Farm' description: '' location: lat: -25.91 lng: 28.12 isUnassigned: false properties: data: type: object properties: uuid: type: string example: c9b4c54e-a135-4a7f-86c9-7f03b9329a1b description: 'The unique identifier of the farm' createdAt: type: string example: '2024-01-03T20:11:13+00:00' description: 'The timestamp when the farm was created' updatedAt: type: string example: '2024-01-03T20:11:13+00:00' description: 'The timestamp when the farm was last updated' enabled: type: boolean example: true description: 'Whether the farm is enabled' companySlug: type: string example: tracklab description: 'The slug of the company this farm belongs to' name: type: string example: 'First Farm' description: 'The name of the farm' description: type: string example: '' description: 'The description of the farm' location: type: object properties: lat: type: number example: -25.91 description: 'The latitude coordinate' lng: type: number example: 28.12 description: 'The longitude coordinate' description: 'The location coordinates' isUnassigned: type: boolean example: false tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: name: type: string description: 'The name of the farm.' example: 'North Field Farm' description: type: string description: 'The description of the farm.' example: 'Main production farm' nullable: true location: type: object description: '' example: [] properties: latitude: type: numeric description: 'The latitude coordinate between -90 and 90.' example: '51.509865' longitude: type: numeric description: 'The longitude coordinate between -180 and 180.' example: '-0.118092' required: - latitude - longitude required: - name parameters: - in: path name: company_slug description: 'The slug of the company.' example: dolorem required: true schema: type: string '/api/v1/c/{company_slug}/farm/{farm_uuid}': get: summary: 'Get Farm Details' operationId: getFarmDetails description: 'Retrieve details of a specific farm.' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: uuid: c9b4c54e-a135-4a7f-86c9-7f03b9329a1b createdAt: '2024-01-03T20:11:13+00:00' updatedAt: '2024-01-03T20:11:13+00:00' enabled: true companySlug: tracklab name: 'First Farm' description: '' location: lat: -25.91 lng: 28.12 isUnassigned: false properties: data: type: object properties: uuid: type: string example: c9b4c54e-a135-4a7f-86c9-7f03b9329a1b description: 'The unique identifier of the farm' createdAt: type: string example: '2024-01-03T20:11:13+00:00' description: 'The timestamp when the farm was created' updatedAt: type: string example: '2024-01-03T20:11:13+00:00' description: 'The timestamp when the farm was last updated' enabled: type: boolean example: true description: 'Whether the farm is enabled' companySlug: type: string example: tracklab description: 'The slug of the company this farm belongs to' name: type: string example: 'First Farm' description: 'The name of the farm' description: type: string example: '' description: 'The description of the farm' location: type: object properties: lat: type: number example: -25.91 description: 'The latitude coordinate' lng: type: number example: 28.12 description: 'The longitude coordinate' description: 'The location coordinates' isUnassigned: type: boolean example: false tags: - Endpoints put: summary: 'Update Farm' operationId: updateFarm description: "Update an existing farm's details." parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: uuid: 550e8400-e29b-41d4-a716-446655440000 name: 'Updated Farm Name' description: 'Updated farm description' location: latitude: 51.509865 longitude: -0.118092 created_at: '2024-01-20T12:00:00Z' updated_at: '2024-01-20T12:00:00Z' properties: data: type: object properties: uuid: type: string example: 550e8400-e29b-41d4-a716-446655440000 name: type: string example: 'Updated Farm Name' description: type: string example: 'Updated farm description' location: type: object properties: latitude: type: number example: 51.509865 longitude: type: number example: -0.118092 created_at: type: string example: '2024-01-20T12:00:00Z' updated_at: type: string example: '2024-01-20T12:00:00Z' tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: name: type: string description: 'The name of the farm.' example: 'North Field Farm' description: type: string description: 'The description of the farm.' example: 'Main production farm' nullable: true location: type: object description: '' example: [] properties: latitude: type: numeric description: 'The latitude coordinate between -90 and 90.' example: '51.509865' longitude: type: numeric description: 'The longitude coordinate between -180 and 180.' example: '-0.118092' required: - latitude - longitude required: - name parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: farm_uuid description: '' example: c9b4c54e-a135-4a7f-86c9-7f03b9329a1b required: true schema: type: string - in: path name: company description: 'The slug of the company' example: incidunt required: true schema: type: string - in: path name: farm description: 'The UUID of the farm' example: temporibus required: true schema: type: string '/api/v1/c/{company_slug}/farm/{farm_uuid}/collector': get: summary: 'Get Farm Collectors' operationId: getFarmCollectors description: '' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: - uuid: aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa createdAt: '2026-02-12T13:40:48+00:00' updatedAt: '2026-02-12T13:40:48+00:00' enabled: true companySlug: tracklab farmUuid: c9b4c54e-a135-4a7f-86c9-7f03b9329a1b collectorTypeSlug: ncu type: NCU parentUuid: null childrenUuids: [] serial: SYSTEM-HOLDING-NCU name: 'Unassigned Collectors' description: 'System-level holding NCU for auto-subscribed collectors awaiting assignment' location: null isDecommissioned: false decommissionedAt: null decommissionReason: null currentTracker: null status: null hardwareVersion: null currentFirmware: null manufacturedAt: null deployedAt: null retiredAt: null - uuid: aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa createdAt: '2026-02-12T13:40:48+00:00' updatedAt: '2026-02-12T13:40:48+00:00' enabled: true companySlug: tracklab farmUuid: c9b4c54e-a135-4a7f-86c9-7f03b9329a1b collectorTypeSlug: ncu type: NCU parentUuid: null childrenUuids: [] serial: SYSTEM-HOLDING-NCU name: 'Unassigned Collectors' description: 'System-level holding NCU for auto-subscribed collectors awaiting assignment' location: null isDecommissioned: false decommissionedAt: null decommissionReason: null currentTracker: null status: null hardwareVersion: null currentFirmware: null manufacturedAt: null deployedAt: null retiredAt: null properties: data: type: array example: - uuid: aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa createdAt: '2026-02-12T13:40:48+00:00' updatedAt: '2026-02-12T13:40:48+00:00' enabled: true companySlug: tracklab farmUuid: c9b4c54e-a135-4a7f-86c9-7f03b9329a1b collectorTypeSlug: ncu type: NCU parentUuid: null childrenUuids: [] serial: SYSTEM-HOLDING-NCU name: 'Unassigned Collectors' description: 'System-level holding NCU for auto-subscribed collectors awaiting assignment' location: null isDecommissioned: false decommissionedAt: null decommissionReason: null currentTracker: null status: null hardwareVersion: null currentFirmware: null manufacturedAt: null deployedAt: null retiredAt: null - uuid: aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa createdAt: '2026-02-12T13:40:48+00:00' updatedAt: '2026-02-12T13:40:48+00:00' enabled: true companySlug: tracklab farmUuid: c9b4c54e-a135-4a7f-86c9-7f03b9329a1b collectorTypeSlug: ncu type: NCU parentUuid: null childrenUuids: [] serial: SYSTEM-HOLDING-NCU name: 'Unassigned Collectors' description: 'System-level holding NCU for auto-subscribed collectors awaiting assignment' location: null isDecommissioned: false decommissionedAt: null decommissionReason: null currentTracker: null status: null hardwareVersion: null currentFirmware: null manufacturedAt: null deployedAt: null retiredAt: null items: type: object properties: uuid: type: string example: aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa description: 'The unique identifier of the collector' createdAt: type: string example: '2026-02-12T13:40:48+00:00' description: 'The creation timestamp (ISO8601)' updatedAt: type: string example: '2026-02-12T13:40:48+00:00' description: 'The last update timestamp (ISO8601)' enabled: type: boolean example: true description: 'Whether the collector is enabled' companySlug: type: string example: tracklab description: 'The slug of the company this collector belongs to' farmUuid: type: string example: c9b4c54e-a135-4a7f-86c9-7f03b9329a1b description: 'The UUID of the farm this collector belongs to' collectorTypeSlug: type: string example: ncu description: 'The slug of the collector type' type: type: string example: NCU description: 'The type of collector (NCU or TCU)' parentUuid: type: string example: null description: 'The UUID of the parent collector (for TCUs)' childrenUuids: type: array example: [] description: 'Array of child collector UUIDs (for NCUs)' serial: type: string example: SYSTEM-HOLDING-NCU description: 'The serial number of the collector' name: type: string example: 'Unassigned Collectors' description: 'The name of the collector' description: type: string example: 'System-level holding NCU for auto-subscribed collectors awaiting assignment' description: 'The description of the collector' location: type: string example: null description: 'The location coordinates' isDecommissioned: type: boolean example: false description: 'Whether the collector is decommissioned' decommissionedAt: type: string example: null description: 'The decommission timestamp (ISO8601)' decommissionReason: type: string example: null description: 'The reason for decommission' currentTracker: type: string example: null description: 'The current tracker placement' status: type: string example: null description: 'The current lifecycle status' hardwareVersion: type: string example: null description: 'The hardware version type' currentFirmware: type: string example: null description: 'The current firmware information' manufacturedAt: type: string example: null description: 'The manufacture timestamp (ISO8601)' deployedAt: type: string example: null description: 'The deployment timestamp (ISO8601)' retiredAt: type: string example: null description: 'The retirement timestamp (ISO8601)' tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: farm_uuid description: '' example: c9b4c54e-a135-4a7f-86c9-7f03b9329a1b required: true schema: type: string '/api/v1/c/{company_slug}/farm/{farm_uuid}/sections': get: summary: 'List sections for a farm' operationId: listSectionsForAFarm description: "Returns paginated list of sections for a farm belonging to the company.\nUse this to get section UUIDs when moving collectors." parameters: - in: query name: enabled_only description: 'Filter to only enabled sections.' example: true required: false schema: type: boolean description: 'Filter to only enabled sections.' example: true - in: query name: page description: 'Page number.' example: 1 required: false schema: type: integer description: 'Page number.' example: 1 - in: query name: perPage description: 'Results per page (max 100).' example: 25 required: false schema: type: integer description: 'Results per page (max 100).' example: 25 responses: 200: description: '' content: application/json: schema: type: object example: data: - uuid: 147594ba-6f75-4b06-9daf-4c9dc58b34c1 name: Unassigned description: '' enabled: true orderColumn: 0 location: null locationJson: null metadata: null createdAt: '2026-01-14T19:48:46+00:00' updatedAt: '2026-01-16T10:41:36+00:00' isUnassigned: true - uuid: 147594ba-6f75-4b06-9daf-4c9dc58b34c1 name: Unassigned description: '' enabled: true orderColumn: 0 location: null locationJson: null metadata: null createdAt: '2026-01-14T19:48:46+00:00' updatedAt: '2026-01-16T10:41:36+00:00' isUnassigned: true properties: data: type: array example: - uuid: 147594ba-6f75-4b06-9daf-4c9dc58b34c1 name: Unassigned description: '' enabled: true orderColumn: 0 location: null locationJson: null metadata: null createdAt: '2026-01-14T19:48:46+00:00' updatedAt: '2026-01-16T10:41:36+00:00' isUnassigned: true - uuid: 147594ba-6f75-4b06-9daf-4c9dc58b34c1 name: Unassigned description: '' enabled: true orderColumn: 0 location: null locationJson: null metadata: null createdAt: '2026-01-14T19:48:46+00:00' updatedAt: '2026-01-16T10:41:36+00:00' isUnassigned: true items: type: object properties: uuid: type: string example: 147594ba-6f75-4b06-9daf-4c9dc58b34c1 name: type: string example: Unassigned description: type: string example: '' enabled: type: boolean example: true orderColumn: type: integer example: 0 location: type: string example: null nullable: true locationJson: type: string example: null nullable: true metadata: type: string example: null nullable: true createdAt: type: string example: '2026-01-14T19:48:46+00:00' updatedAt: type: string example: '2026-01-16T10:41:36+00:00' isUnassigned: type: boolean example: true tags: - Endpoints post: summary: 'Create a new farm section' operationId: createANewFarmSection description: 'Creates a section within a specific farm. Requires FARM_UPDATE permission.' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: uuid: 147594ba-6f75-4b06-9daf-4c9dc58b34c1 name: Unassigned description: '' enabled: true orderColumn: 0 location: null locationJson: null metadata: null createdAt: '2026-01-14T19:48:46+00:00' updatedAt: '2026-01-16T10:41:36+00:00' isUnassigned: true properties: data: type: object properties: uuid: type: string example: 147594ba-6f75-4b06-9daf-4c9dc58b34c1 name: type: string example: Unassigned description: type: string example: '' enabled: type: boolean example: true orderColumn: type: integer example: 0 location: type: string example: null nullable: true locationJson: type: string example: null nullable: true metadata: type: string example: null nullable: true createdAt: type: string example: '2026-01-14T19:48:46+00:00' updatedAt: type: string example: '2026-01-16T10:41:36+00:00' isUnassigned: type: boolean example: true tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: name: type: string description: 'The name of the section.' example: 'North Field' slug: type: string description: '' example: null description: type: string description: 'The description.' example: 'Northern section of the farm' nullable: true enabled: type: boolean description: 'Whether section is enabled.' example: true orderColumn: type: integer description: 'Display order.' example: 1 locationJson: type: object description: 'Location coordinates.' example: latitude: 51.509865 longitude: -0.118092 properties: latitude: type: number description: 'This field is required when locationJson is present. Must be between -90 and 90.' example: 51.509865 longitude: type: number description: 'This field is required when locationJson is present. Must be between -180 and 180.' example: -0.118092 nullable: true metadata: type: object description: 'Optional metadata.' example: notes: 'Primary section' properties: { } nullable: true required: - name parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: farm_uuid description: '' example: c9b4c54e-a135-4a7f-86c9-7f03b9329a1b required: true schema: type: string - in: path name: company description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: farm description: 'The UUID of the farm.' example: 550e8400-e29b-41d4-a716-446655440000 required: true schema: type: string '/api/v1/c/{company_slug}/firmware-keys/workflows/provision': post: summary: '' operationId: postApiV1CCompany_slugFirmwareKeysWorkflowsProvision description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: name: type: string description: 'Name for the firmware access key. Must not be greater than 255 characters.' example: 'Production Farm Key' description: type: string description: 'Description of the key purpose.' example: 'Key for firmware updates on production farm' nullable: true farmUuid: type: string description: 'UUID of the farm to provision the key for. Must be a valid UUID.' example: 550e8400-e29b-41d4-a716-446655440000 expiresAt: type: string description: 'Expiration date for the key. Must be a valid date.' example: '2025-12-31' nullable: true isActive: type: boolean description: 'Whether the key is active.' example: true plainKey: type: string description: 'Pre-generated key value (optional, auto-generated if not provided). Must be at least 24 characters.' example: abc123def456ghi789jkl012 nullable: true required: - name - farmUuid parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string '/api/v1/c/{company_slug}/firmware-keys': get: summary: '' operationId: getApiV1CCompany_slugFirmwareKeys description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints post: summary: '' operationId: postApiV1CCompany_slugFirmwareKeys description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: name: type: string description: 'Name for the firmware access key. Must not be greater than 255 characters.' example: 'Production Farm Key' description: type: string description: 'Description of the key purpose.' example: 'Key for firmware updates on production farm' nullable: true farmUuid: type: string description: 'UUID of the farm to create the key for. Must be a valid UUID.' example: 550e8400-e29b-41d4-a716-446655440000 expiresAt: type: string description: 'Expiration date for the key. Must be a valid date.' example: '2025-12-31' nullable: true isActive: type: boolean description: 'Whether the key is active.' example: true required: - name - farmUuid parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string '/api/v1/c/{company_slug}/firmware-keys/{firmwareAccessKey_uuid}': get: summary: '' operationId: getApiV1CCompany_slugFirmwareKeysFirmwareAccessKey_uuid description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints put: summary: '' operationId: putApiV1CCompany_slugFirmwareKeysFirmwareAccessKey_uuid description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: false content: application/json: schema: type: object properties: name: type: string description: 'Name for the firmware access key. Must not be greater than 255 characters.' example: 'Updated Farm Key' description: type: string description: 'Description of the key purpose.' example: 'Updated key description' expiresAt: type: string description: 'Expiration date for the key. Must be a valid date.' example: '2026-06-30' nullable: true isActive: type: boolean description: 'Whether the key is active.' example: false parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: firmwareAccessKey_uuid description: '' example: f2c02d5b-8653-47d4-b315-5d073c2da271 required: true schema: type: string '/api/v1/c/{company_slug}/firmware-keys/{firmwareAccessKey_uuid}/deactivate': put: summary: '' operationId: putApiV1CCompany_slugFirmwareKeysFirmwareAccessKey_uuidDeactivate description: '' parameters: [] responses: { } tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: firmwareAccessKey_uuid description: '' example: f2c02d5b-8653-47d4-b315-5d073c2da271 required: true schema: type: string '/api/v1/c/{company_slug}/invitations': get: summary: 'List Company Invitations' operationId: listCompanyInvitations description: 'Returns all invitations for the company.' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: - uuid: null email: null status: null roleSlug: null invitedBy: uuid: null name: null validUntil: '2026-03-26T23:05:08+00:00' acceptedAt: null createdAt: '2026-03-26T23:05:08+00:00' - uuid: null email: null status: null roleSlug: null invitedBy: uuid: null name: null validUntil: '2026-03-26T23:05:08+00:00' acceptedAt: null createdAt: '2026-03-26T23:05:08+00:00' properties: data: type: array example: - uuid: null email: null status: null roleSlug: null invitedBy: uuid: null name: null validUntil: '2026-03-26T23:05:08+00:00' acceptedAt: null createdAt: '2026-03-26T23:05:08+00:00' - uuid: null email: null status: null roleSlug: null invitedBy: uuid: null name: null validUntil: '2026-03-26T23:05:08+00:00' acceptedAt: null createdAt: '2026-03-26T23:05:08+00:00' items: type: object properties: uuid: type: string example: null nullable: true email: type: string example: null nullable: true status: type: string example: null nullable: true roleSlug: type: string example: null nullable: true invitedBy: type: object properties: uuid: type: string example: null nullable: true name: type: string example: null nullable: true validUntil: type: string example: '2026-03-26T23:05:08+00:00' acceptedAt: type: string example: null nullable: true createdAt: type: string example: '2026-03-26T23:05:08+00:00' tags: - Endpoints post: summary: 'Create Invitation' operationId: createInvitation description: 'Creates a new invitation and sends email to the invitee.' parameters: [] responses: 201: description: '' content: application/json: schema: type: object example: data: uuid: 550e8400-e29b-41d4-a716-446655440000 email: user@example.com status: pending roleSlug: user validUntil: '2026-01-26T00:00:00+00:00' properties: data: type: object properties: uuid: type: string example: 550e8400-e29b-41d4-a716-446655440000 email: type: string example: user@example.com status: type: string example: pending roleSlug: type: string example: user validUntil: type: string example: '2026-01-26T00:00:00+00:00' tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: email: type: string description: 'The email address to invite.' example: user@example.com roleSlug: type: string description: 'The role to assign on acceptance.' example: user required: - email - roleSlug parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string '/api/v1/c/{company_slug}/invitations/{uuid}': delete: summary: 'Revoke Invitation' operationId: revokeInvitation description: 'Revokes a pending invitation.' parameters: [] responses: { } tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: uuid description: '' example: 4ac83d17-dbf5-30b5-af64-4f53a2991f81 required: true schema: type: string - in: path name: company description: 'The company slug.' example: acme-corp required: true schema: type: string - in: path name: invitation description: 'The invitation UUID.' example: 550e8400-e29b-41d4-a716-446655440000 required: true schema: type: string '/api/v1/c/{company_slug}/measurements': get: summary: 'Query Measurements' operationId: queryMeasurements description: 'Query measurement data with support for multiple types, collectors, farms, and aggregation methods.' parameters: - in: query name: types description: 'The slug of an existing record in the collector_measurement_types table.' example: - officiis required: false schema: type: array description: 'The slug of an existing record in the collector_measurement_types table.' example: - officiis items: type: string - in: query name: from description: 'datetime Start date for filtering (ISO 8601).' example: '2024-01-01T00:00:00Z' required: true schema: type: string description: 'datetime Start date for filtering (ISO 8601).' example: '2024-01-01T00:00:00Z' - in: query name: collectorUuids description: 'The uuid of an existing record in the collectors table.' example: - et required: false schema: type: array description: 'The uuid of an existing record in the collectors table.' example: - et items: type: string - in: query name: farmUuid description: 'Filter by farm UUID' example: 35ee6e6b-fae8-3429-a183-f727f6583abf required: false schema: type: string description: 'Filter by farm UUID' example: 35ee6e6b-fae8-3429-a183-f727f6583abf nullable: true - in: query name: farmSectionUuid description: 'Filter by farm section UUID' example: 05acbf2c-8d8f-3ffb-9595-569bf5e5c8c6 required: false schema: type: string description: 'Filter by farm section UUID' example: 05acbf2c-8d8f-3ffb-9595-569bf5e5c8c6 nullable: true - in: query name: collectorTypeSlug description: "Filter by collector type (e.g., 'ncu', 'tcu')" example: dolorem required: false schema: type: string description: "Filter by collector type (e.g., 'ncu', 'tcu')" example: dolorem nullable: true - in: query name: to description: 'datetime End date for filtering (ISO 8601).' example: '2024-01-31T23:59:59Z' required: false schema: type: string description: 'datetime End date for filtering (ISO 8601).' example: '2024-01-31T23:59:59Z' nullable: true - in: query name: raw description: 'Return raw data without aggregation. Default: false' example: true required: false schema: type: boolean description: 'Return raw data without aggregation. Default: false' example: true nullable: true - in: query name: period description: 'Aggregation period slug (overrides auto-selection).' example: 1-hour required: false schema: type: string description: 'Aggregation period slug (overrides auto-selection).' example: 1-hour nullable: true - in: query name: aggregation description: 'Aggregation method slug from `measurement_aggregation_types` (see `/api/v1/type/data/measurement-aggregation`). Default: avg' example: natus required: false schema: type: string description: 'Aggregation method slug from `measurement_aggregation_types` (see `/api/v1/type/data/measurement-aggregation`). Default: avg' example: natus nullable: true - in: query name: valueMin description: 'numeric Exclude values below threshold' example: eaque required: false schema: type: string description: 'numeric Exclude values below threshold' example: eaque nullable: true - in: query name: valueMax description: 'numeric Exclude values above threshold' example: occaecati required: false schema: type: string description: 'numeric Exclude values above threshold' example: occaecati nullable: true - in: query name: groupBy description: 'Grouping: measurement_type, collector, farm_section, time_bucket, tracker. Default: measurement_type' example: error required: false schema: type: string description: 'Grouping: measurement_type, collector, farm_section, time_bucket, tracker. Default: measurement_type' example: error nullable: true - in: query name: includeMetadata description: 'Include collector info with data. Default: false' example: true required: false schema: type: boolean description: 'Include collector info with data. Default: false' example: true nullable: true - in: query name: includeReplacements description: 'Include collector replacement history on the same tracker(s) when querying by collector UUIDs. Default: false' example: false required: false schema: type: boolean description: 'Include collector replacement history on the same tracker(s) when querying by collector UUIDs. Default: false' example: false nullable: true - in: query name: includeCount description: 'Include sample count per bucket. Default: false' example: true required: false schema: type: boolean description: 'Include sample count per bucket. Default: false' example: true nullable: true - in: query name: exportType description: 'Export format: json, csv, xml, excel. Default: json' example: molestiae required: false schema: type: string description: 'Export format: json, csv, xml, excel. Default: json' example: molestiae nullable: true - in: query name: page description: 'Page number. Default: 1' example: 2 required: false schema: type: integer description: 'Page number. Default: 1' example: 2 nullable: true - in: query name: perPage description: 'Items per page (max 10000). Default: 100' example: 7 required: false schema: type: integer description: 'Items per page (max 10000). Default: 100' example: 7 nullable: true - in: query name: 'types[]' description: 'Array of measurement type slugs.' example: - temperature - humidity required: true schema: type: array description: 'Array of measurement type slugs.' example: - temperature - humidity items: type: string - in: query name: 'collectorUuids[]' description: 'Filter by specific collector UUIDs' example: - at required: false schema: type: array description: 'Filter by specific collector UUIDs' example: - at items: type: string responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: company description: 'The slug of the company' example: dolorem required: true schema: type: string '/api/v1/c/{company_slug}/measurements/download-link': post: summary: 'Generate a short-lived signed download link for measurements.' operationId: generateAShortLivedSignedDownloadLinkForMeasurements description: '' parameters: - in: query name: types description: 'The slug of an existing record in the collector_measurement_types table.' example: - tenetur required: false schema: type: array description: 'The slug of an existing record in the collector_measurement_types table.' example: - tenetur items: type: string - in: query name: from description: 'Start timestamp (ISO 8601). Must be a valid date. Must be a date before now.' example: '2025-01-01T00:00:00Z' required: true schema: type: string description: 'Start timestamp (ISO 8601). Must be a valid date. Must be a date before now.' example: '2025-01-01T00:00:00Z' - in: query name: collectorUuids description: 'The uuid of an existing record in the collectors table.' example: - ipsam required: false schema: type: array description: 'The uuid of an existing record in the collectors table.' example: - ipsam items: type: string - in: query name: farmUuid description: 'Filter by farm UUID. The uuid of an existing record in the farms table.' example: d5b1b4e7-2d71-4c16-9c0c-fc0c2b9f3d0d required: false schema: type: string description: 'Filter by farm UUID. The uuid of an existing record in the farms table.' example: d5b1b4e7-2d71-4c16-9c0c-fc0c2b9f3d0d nullable: true - in: query name: farmSectionUuid description: 'Filter by farm section UUID. The uuid of an existing record in the farm_sections table.' example: 3b3fb893-1e88-4c3c-8b10-0a5c2b3cf6aa required: false schema: type: string description: 'Filter by farm section UUID. The uuid of an existing record in the farm_sections table.' example: 3b3fb893-1e88-4c3c-8b10-0a5c2b3cf6aa nullable: true - in: query name: collectorTypeSlug description: 'Filter by collector type slug. The slug of an existing record in the collector_types table.' example: ncu required: false schema: type: string description: 'Filter by collector type slug. The slug of an existing record in the collector_types table.' example: ncu nullable: true - in: query name: to description: 'End timestamp (ISO 8601). Must be a valid date. Must be a date after from.' example: '2025-01-02T00:00:00Z' required: false schema: type: string description: 'End timestamp (ISO 8601). Must be a valid date. Must be a date after from.' example: '2025-01-02T00:00:00Z' nullable: true - in: query name: raw description: 'When true, returns raw measurements without aggregation.' example: false required: false schema: type: boolean description: 'When true, returns raw measurements without aggregation.' example: false nullable: true - in: query name: period description: 'Aggregation period type slug (when raw=false). The slug of an existing record in the period_types table.' example: minute required: false schema: type: string description: 'Aggregation period type slug (when raw=false). The slug of an existing record in the period_types table.' example: minute nullable: true - in: query name: aggregation description: 'Aggregation method slug (enabled aggregation types only). The slug of an existing record in the measurement_aggregation_types table.' example: avg required: false schema: type: string description: 'Aggregation method slug (enabled aggregation types only). The slug of an existing record in the measurement_aggregation_types table.' example: avg nullable: true - in: query name: valueMin description: 'Minimum measurement value filter.' example: 0.0 required: false schema: type: number description: 'Minimum measurement value filter.' example: 0.0 nullable: true - in: query name: valueMax description: 'Maximum measurement value filter.' example: 1000.0 required: false schema: type: number description: 'Maximum measurement value filter.' example: 1000.0 nullable: true - in: query name: groupBy description: 'Group results by dimension.' example: measurement_type required: false schema: type: string description: 'Group results by dimension.' example: measurement_type enum: - measurement_type - collector - farm_section - time_bucket - tracker nullable: true - in: query name: includeMetadata description: 'Include measurement type / collector metadata.' example: true required: false schema: type: boolean description: 'Include measurement type / collector metadata.' example: true nullable: true - in: query name: includeReplacements description: 'When querying by collector UUIDs, include collector history on the same tracker(s) across handovers.' example: false required: false schema: type: boolean description: 'When querying by collector UUIDs, include collector history on the same tracker(s) across handovers.' example: false nullable: true - in: query name: includeCount description: 'Include total record count per group.' example: false required: false schema: type: boolean description: 'Include total record count per group.' example: false nullable: true - in: query name: exportType description: 'Optional export format.' example: json required: false schema: type: string description: 'Optional export format.' example: json enum: - json - csv - xml - excel nullable: true - in: query name: page description: 'Page number for pagination. Must be at least 1.' example: 1 required: false schema: type: integer description: 'Page number for pagination. Must be at least 1.' example: 1 nullable: true - in: query name: perPage description: 'Items per page (max 10000). Must be at least 1. Must not be greater than 10000.' example: 100 required: false schema: type: integer description: 'Items per page (max 10000). Must be at least 1. Must not be greater than 10000.' example: 100 nullable: true - in: query name: expiresInMinutes description: 'Link expiry time in minutes (max 10). Must be at least 1. Must not be greater than 10.' example: 10 required: false schema: type: integer description: 'Link expiry time in minutes (max 10). Must be at least 1. Must not be greater than 10.' example: 10 nullable: true responses: { } tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string '/api/v1/c/{company_slug}/notification-channels': get: summary: '' operationId: getApiV1CCompany_slugNotificationChannels description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints post: summary: '' operationId: postApiV1CCompany_slugNotificationChannels description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: companySlug: type: string description: 'Company slug for this channel. The slug of an existing record in the companies table.' example: acme-solar farmUuid: type: string description: 'Optional farm UUID for farm-scoped channels. Must be a valid UUID. The uuid of an existing record in the farms table.' example: 550e8400-e29b-41d4-a716-446655440111 nullable: true notificationChannelType: type: string description: 'Notification channel type slug. The slug of an existing record in the notification_channel_types table.' example: email name: type: string description: 'Display name of the notification channel. Must not be greater than 255 characters.' example: 'Ops Email Alerts' required: - companySlug - notificationChannelType - name parameters: - in: path name: company_slug description: 'The slug of the company.' example: delectus required: true schema: type: string '/api/v1/c/{company_slug}/notification-channels/{notificationChannel_uuid}': get: summary: '' operationId: getApiV1CCompany_slugNotificationChannelsNotificationChannel_uuid description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints put: summary: '' operationId: putApiV1CCompany_slugNotificationChannelsNotificationChannel_uuid description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: false content: application/json: schema: type: object properties: notificationChannelType: type: string description: 'Notification channel type slug. The slug of an existing record in the notification_channel_types table.' example: email nullable: true name: type: string description: 'Display name of the notification channel. Must not be greater than 255 characters.' example: 'Operations Alerts' nullable: true delete: summary: '' operationId: deleteApiV1CCompany_slugNotificationChannelsNotificationChannel_uuid description: '' parameters: [] responses: { } tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: notificationChannel_uuid description: '' example: 7d93c65a-144a-3efd-b48a-78a4e7d72450 required: true schema: type: string '/api/v1/c/{company_slug}/notification-channels/{notificationChannel_uuid}/emails': post: summary: '' operationId: postApiV1CCompany_slugNotificationChannelsNotificationChannel_uuidEmails description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: emailAddress: type: string description: 'Email address to receive notifications. Must be a valid email address. Must not be greater than 255 characters.' example: alerts@example.com required: - emailAddress parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: notificationChannel_uuid description: '' example: 8152214e-3f89-3e0a-824d-5fe7663d9afb required: true schema: type: string '/api/v1/c/{company_slug}/notification-channels/{notificationChannel_uuid}/push-devices': post: summary: '' operationId: postApiV1CCompany_slugNotificationChannelsNotificationChannel_uuidPushDevices description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: mobileDeviceUuid: type: string description: 'UUID of the mobile device to link for push notifications. Must be a valid UUID. The uuid of an existing record in the mobile_devices table.' example: 550e8400-e29b-41d4-a716-446655440000 required: - mobileDeviceUuid parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: notificationChannel_uuid description: '' example: efaa4a0d-de47-3124-bf91-71c1c4629636 required: true schema: type: string '/api/v1/c/{company_slug}/notification-channels/{notificationChannel_uuid}/webhooks': post: summary: '' operationId: postApiV1CCompany_slugNotificationChannelsNotificationChannel_uuidWebhooks description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: name: type: string description: 'Webhook name. Must not be greater than 255 characters.' example: 'PagerDuty Webhook' url: type: string description: 'Webhook URL endpoint. Must be a valid URL. Must not be greater than 2048 characters.' example: 'https://hooks.example.com/alerts' httpMethod: type: string description: 'HTTP method used for webhook delivery.' example: POST enum: - POST - PUT - PATCH - DELETE nullable: true timeoutSeconds: type: integer description: 'Webhook timeout in seconds. Must be at least 1. Must not be greater than 120.' example: 30 nullable: true required: - name - url parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: notificationChannel_uuid description: '' example: 93d73d1e-d06c-3dde-83bf-ff208ffd9e4c required: true schema: type: string '/api/v1/c/{company_slug}/notification-channel-emails/{notificationChannelEmail_uuid}': delete: summary: '' operationId: deleteApiV1CCompany_slugNotificationChannelEmailsNotificationChannelEmail_uuid description: '' parameters: [] responses: { } tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: notificationChannelEmail_uuid description: '' example: 4fa4e220-5e7f-387e-a7e5-685efe3f5158 required: true schema: type: string '/api/v1/c/{company_slug}/notification-channel-push-devices/{notificationChannelPushDevice_uuid}': delete: summary: '' operationId: deleteApiV1CCompany_slugNotificationChannelPushDevicesNotificationChannelPushDevice_uuid description: '' parameters: [] responses: { } tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: notificationChannelPushDevice_uuid description: '' example: 14174b37-e53f-30d7-9da6-572aefc6f13c required: true schema: type: string '/api/v1/c/{company_slug}/notification-channel-webhooks/{notificationChannelWebhook_uuid}': put: summary: '' operationId: putApiV1CCompany_slugNotificationChannelWebhooksNotificationChannelWebhook_uuid description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: false content: application/json: schema: type: object properties: name: type: string description: 'Webhook name. Must not be greater than 255 characters.' example: 'PagerDuty Webhook' nullable: true url: type: string description: 'Webhook URL endpoint. Must be a valid URL. Must not be greater than 2048 characters.' example: 'https://hooks.example.com/alerts' nullable: true httpMethod: type: string description: 'HTTP method used for webhook delivery.' example: PATCH enum: - POST - PUT - PATCH - DELETE nullable: true timeoutSeconds: type: integer description: 'Webhook timeout in seconds. Must be at least 1. Must not be greater than 120.' example: 20 nullable: true delete: summary: '' operationId: deleteApiV1CCompany_slugNotificationChannelWebhooksNotificationChannelWebhook_uuid description: '' parameters: [] responses: { } tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: notificationChannelWebhook_uuid description: '' example: f166f8f9-765c-3e10-b7a2-67a54344648e required: true schema: type: string '/api/v1/c/{company_slug}/notification-channel-webhooks/{notificationChannelWebhook_uuid}/headers': post: summary: '' operationId: postApiV1CCompany_slugNotificationChannelWebhooksNotificationChannelWebhook_uuidHeaders description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: headerKey: type: string description: 'Webhook header key. Must not be greater than 255 characters.' example: X-Signature headerValue: type: string description: 'Webhook header value. Must not be greater than 1000 characters.' example: secret-token required: - headerKey - headerValue parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: notificationChannelWebhook_uuid description: '' example: 95324a82-1f6e-367d-b883-2b3737ad37c4 required: true schema: type: string '/api/v1/c/{company_slug}/notification-channel-webhook-headers/{notificationChannelWebhookHeader_uuid}': delete: summary: '' operationId: deleteApiV1CCompany_slugNotificationChannelWebhookHeadersNotificationChannelWebhookHeader_uuid description: '' parameters: [] responses: { } tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: notificationChannelWebhookHeader_uuid description: '' example: 3dc980bf-064e-34e5-a955-5d980b1af527 required: true schema: type: string '/api/v1/c/{company_slug}/notification-templates': get: summary: '' operationId: getApiV1CCompany_slugNotificationTemplates description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints post: summary: '' operationId: postApiV1CCompany_slugNotificationTemplates description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: notificationChannelType: type: string description: 'Notification channel type slug. The slug of an existing record in the notification_channel_types table.' example: email notificationTemplateFormatType: type: string description: 'Notification template format type slug. The slug of an existing record in the notification_template_format_types table.' example: text name: type: string description: 'Template name. Must not be greater than 255 characters.' example: 'Critical Alert Template' subjectTemplate: type: string description: 'Optional subject template. Supports double-curly-brace placeholders: ruleName, collectorName, triggeredValue, conditionOperator, conditionThreshold, triggeredAt, companyName, farmName. Must not be greater than 500 characters.' example: '[Alert] Collector Offline' nullable: true bodyTemplate: type: string description: 'Template body content. Supports double-curly-brace placeholders: ruleName, collectorName, triggeredValue, conditionOperator, conditionThreshold, triggeredAt, companyName, farmName.' example: 'Alert: Collector went offline at Farm Alpha.' required: - notificationChannelType - notificationTemplateFormatType - name - bodyTemplate parameters: - in: path name: company_slug description: 'The slug of the company.' example: sint required: true schema: type: string '/api/v1/c/{company_slug}/notification-templates/{notificationTemplate_uuid}': get: summary: '' operationId: getApiV1CCompany_slugNotificationTemplatesNotificationTemplate_uuid description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints put: summary: '' operationId: putApiV1CCompany_slugNotificationTemplatesNotificationTemplate_uuid description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: false content: application/json: schema: type: object properties: notificationChannelType: type: string description: 'Notification channel type slug. The slug of an existing record in the notification_channel_types table.' example: email nullable: true notificationTemplateFormatType: type: string description: 'Notification template format type slug. The slug of an existing record in the notification_template_format_types table.' example: html nullable: true name: type: string description: 'Template name. Must not be greater than 255 characters.' example: 'Updated Alert Template' nullable: true subjectTemplate: type: string description: 'Optional subject template. Supports double-curly-brace placeholders: ruleName, collectorName, triggeredValue, conditionOperator, conditionThreshold, triggeredAt, companyName, farmName. Must not be greater than 500 characters.' example: '[Updated] Collector Offline' nullable: true bodyTemplate: type: string description: 'Template body content. Supports double-curly-brace placeholders: ruleName, collectorName, triggeredValue, conditionOperator, conditionThreshold, triggeredAt, companyName, farmName.' example: '

Alert rule updated for Collector Alpha.

' nullable: true delete: summary: '' operationId: deleteApiV1CCompany_slugNotificationTemplatesNotificationTemplate_uuid description: '' parameters: [] responses: { } tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: notificationTemplate_uuid description: '' example: d4d5b924-eff1-44a7-bcc9-b271d8207888 required: true schema: type: string '/api/v1/c/{company_slug}/notification-policies': get: summary: '' operationId: getApiV1CCompany_slugNotificationPolicies description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints post: summary: '' operationId: postApiV1CCompany_slugNotificationPolicies description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: companySlug: type: string description: 'Company scope slug. Provide exactly one scope field. The slug of an existing record in the companies table.' example: acme-solar nullable: true farmUuid: type: string description: 'Farm scope UUID. Provide exactly one scope field. Must be a valid UUID. The uuid of an existing record in the farms table.' example: 550e8400-e29b-41d4-a716-446655440121 nullable: true collectorUuid: type: string description: 'Collector scope UUID. Provide exactly one scope field. Must be a valid UUID. The uuid of an existing record in the collectors table.' example: 550e8400-e29b-41d4-a716-446655440122 nullable: true name: type: string description: 'Notification policy name. Must not be greater than 255 characters.' example: 'Critical Weather Policy' enabled: type: boolean description: 'Whether the policy is enabled.' example: true nullable: true notificationChannelUuid: type: string description: 'Notification channel UUID. Must be a valid UUID. The uuid of an existing record in the notification_channels table.' example: 550e8400-e29b-41d4-a716-446655440123 notificationTemplateUuid: type: string description: 'Notification template UUID. Must be a valid UUID. The uuid of an existing record in the notification_templates table.' example: 550e8400-e29b-41d4-a716-446655440124 labels: type: array description: 'Optional key/value label filters.' example: - key: severity value: critical items: type: object nullable: true properties: key: type: string description: 'This field is required when labels is present. Must not be greater than 255 characters.' example: j value: type: string description: 'This field is required when labels is present. Must not be greater than 255 characters.' example: rfeuoqqtixseh required: - name - notificationChannelUuid - notificationTemplateUuid parameters: - in: path name: company_slug description: 'The slug of the company.' example: aut required: true schema: type: string '/api/v1/c/{company_slug}/notification-policies/{notificationPolicy_uuid}': get: summary: '' operationId: getApiV1CCompany_slugNotificationPoliciesNotificationPolicy_uuid description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints put: summary: '' operationId: putApiV1CCompany_slugNotificationPoliciesNotificationPolicy_uuid description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: false content: application/json: schema: type: object properties: name: type: string description: 'Notification policy name. Must not be greater than 255 characters.' example: 'Critical Weather Policy' nullable: true enabled: type: boolean description: 'Whether the policy is enabled.' example: false nullable: true notificationChannelUuid: type: string description: 'Notification channel UUID. Must be a valid UUID. The uuid of an existing record in the notification_channels table.' example: 550e8400-e29b-41d4-a716-446655440223 nullable: true notificationTemplateUuid: type: string description: 'Notification template UUID. Must be a valid UUID. The uuid of an existing record in the notification_templates table.' example: 550e8400-e29b-41d4-a716-446655440224 nullable: true labels: type: array description: 'Optional key/value label filters.' example: - key: site value: north-farm items: type: object nullable: true properties: key: type: string description: 'This field is required when labels is present. Must not be greater than 255 characters.' example: zdbldm value: type: string description: 'This field is required when labels is present. Must not be greater than 255 characters.' example: cboxfsxrvodkshh delete: summary: '' operationId: deleteApiV1CCompany_slugNotificationPoliciesNotificationPolicy_uuid description: '' parameters: [] responses: { } tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: notificationPolicy_uuid description: '' example: 22604c3e-be5f-326a-b804-4e8b052d1e5e required: true schema: type: string '/api/v1/c/{company_slug}/rma': get: summary: 'List RMA requests for the company.' operationId: listRMARequestsForTheCompany description: '' parameters: - in: query name: status description: 'Filter by RMA status slug.' example: requested required: false schema: type: string description: 'Filter by RMA status slug.' example: requested - in: query name: collectorUuid description: 'Filter by collector UUID.' example: 550e8400-e29b-41d4-a716-446655440000 required: false schema: type: string description: 'Filter by collector UUID.' example: 550e8400-e29b-41d4-a716-446655440000 - in: query name: dateFrom description: 'Filter RMA requests created from this date (ISO 8601).' example: '2025-01-01' required: false schema: type: string description: 'Filter RMA requests created from this date (ISO 8601).' example: '2025-01-01' - in: query name: dateTo description: 'Filter RMA requests created up to this date (ISO 8601).' example: '2025-12-31' required: false schema: type: string description: 'Filter RMA requests created up to this date (ISO 8601).' example: '2025-12-31' - in: query name: page description: 'Page number for pagination.' example: 1 required: false schema: type: integer description: 'Page number for pagination.' example: 1 - in: query name: perPage description: 'Number of items per page.' example: 25 required: false schema: type: integer description: 'Number of items per page.' example: 25 responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints post: summary: 'Create a new RMA request.' operationId: createANewRMARequest description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: collectorUuid: type: string description: 'The UUID of the collector.' example: 550e8400-e29b-41d4-a716-446655440000 reason: type: string description: 'The reason for the RMA request.' example: 'Hardware fault detected' description: type: string description: 'optional Additional details.' example: 'Collector stopped responding after firmware update' nullable: true required: - collectorUuid - reason parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: company description: 'The slug of the company' example: at required: true schema: type: string '/api/v1/c/{company_slug}/rma/{rmaRequest_uuid}': get: summary: 'Show RMA request details.' operationId: showRMARequestDetails description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints patch: summary: 'Update RMA status (e.g. shipped-to-vendor with tracking number).' operationId: updateRMAStatusegShippedToVendorWithTrackingNumber description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: trackingNumber: type: string description: 'optional Tracking number for shipment.' example: 1Z999AA10123456784 nullable: true status: type: string description: 'The target status slug.' example: shipped-to-vendor required: - status parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: rmaRequest_uuid description: '' example: 1303375b-5838-3d02-9160-09b2dbe9f4df required: true schema: type: string - in: path name: company description: 'The slug of the company' example: voluptas required: true schema: type: string - in: path name: rmaRequest description: 'The UUID of the RMA request' example: neque required: true schema: type: string '/api/v1/c/{company_slug}/rma/{rmaRequest_uuid}/approve': post: summary: 'Approve an RMA request.' operationId: approveAnRMARequest description: '' parameters: [] responses: { } tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: rmaRequest_uuid description: '' example: f98aac80-670c-3833-ae42-96cf36b40a33 required: true schema: type: string - in: path name: company description: 'The slug of the company' example: nobis required: true schema: type: string - in: path name: rmaRequest description: 'The UUID of the RMA request' example: aut required: true schema: type: string '/api/v1/c/{company_slug}/rma/{rmaRequest_uuid}/reject': post: summary: 'Reject an RMA request.' operationId: rejectAnRMARequest description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: reason: type: string description: 'The reason for rejection.' example: 'Collector is under warranty with manufacturer' required: - reason parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: rmaRequest_uuid description: '' example: 45b7c84b-25f9-3a7a-a690-66c3b5ae1207 required: true schema: type: string - in: path name: company description: 'The slug of the company' example: qui required: true schema: type: string - in: path name: rmaRequest description: 'The UUID of the RMA request' example: sapiente required: true schema: type: string '/api/v1/c/{company_slug}/rma/{rmaRequest_uuid}/notes': get: summary: 'List notes for an RMA request.' operationId: listNotesForAnRMARequest description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints post: summary: 'Add a note to an RMA request.' operationId: addANoteToAnRMARequest description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: note: type: string description: 'The note content.' example: 'Customer contacted regarding shipping label' required: - note parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: rmaRequest_uuid description: '' example: 89ca5ef1-8f1f-3c9b-a593-7dde5de884c3 required: true schema: type: string - in: path name: company description: 'The slug of the company' example: nulla required: true schema: type: string - in: path name: rmaRequest description: 'The UUID of the RMA request' example: labore required: true schema: type: string '/api/v1/c/{company_slug}/section/{section_uuid}': get: summary: 'Show a farm section' operationId: showAFarmSection description: 'Returns details of a specific farm section. Requires FARM_VIEW permission.' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: uuid: 147594ba-6f75-4b06-9daf-4c9dc58b34c1 name: Unassigned description: '' enabled: true orderColumn: 0 location: null locationJson: null metadata: null createdAt: '2026-01-14T19:48:46+00:00' updatedAt: '2026-01-16T10:41:36+00:00' isUnassigned: true properties: data: type: object properties: uuid: type: string example: 147594ba-6f75-4b06-9daf-4c9dc58b34c1 name: type: string example: Unassigned description: type: string example: '' enabled: type: boolean example: true orderColumn: type: integer example: 0 location: type: string example: null nullable: true locationJson: type: string example: null nullable: true metadata: type: string example: null nullable: true createdAt: type: string example: '2026-01-14T19:48:46+00:00' updatedAt: type: string example: '2026-01-16T10:41:36+00:00' isUnassigned: type: boolean example: true tags: - Endpoints patch: summary: 'Update a farm section' operationId: updateAFarmSection description: "Updates an existing farm section. Requires FARM_UPDATE permission.\nThe \"Unassigned\" section cannot be edited." parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: uuid: 147594ba-6f75-4b06-9daf-4c9dc58b34c1 name: Unassigned description: '' enabled: true orderColumn: 0 location: null locationJson: null metadata: null createdAt: '2026-01-14T19:48:46+00:00' updatedAt: '2026-01-16T10:41:36+00:00' isUnassigned: true properties: data: type: object properties: uuid: type: string example: 147594ba-6f75-4b06-9daf-4c9dc58b34c1 name: type: string example: Unassigned description: type: string example: '' enabled: type: boolean example: true orderColumn: type: integer example: 0 location: type: string example: null nullable: true locationJson: type: string example: null nullable: true metadata: type: string example: null nullable: true createdAt: type: string example: '2026-01-14T19:48:46+00:00' updatedAt: type: string example: '2026-01-16T10:41:36+00:00' isUnassigned: type: boolean example: true tags: - Endpoints requestBody: required: false content: application/json: schema: type: object properties: name: type: string description: 'The name of the section.' example: 'North Field Updated' slug: type: string description: '' example: null description: type: string description: 'The description.' example: 'Updated description' nullable: true enabled: type: boolean description: 'Whether section is enabled.' example: false orderColumn: type: integer description: 'Display order.' example: 2 locationJson: type: object description: 'Location coordinates.' example: latitude: 51.509865 longitude: -0.118092 properties: latitude: type: number description: 'This field is required when locationJson is present. Must be between -90 and 90.' example: 51.509865 longitude: type: number description: 'This field is required when locationJson is present. Must be between -180 and 180.' example: -0.118092 nullable: true metadata: type: object description: 'Optional metadata.' example: notes: 'Updated notes' properties: { } nullable: true delete: summary: 'Delete a farm section' operationId: deleteAFarmSection description: "Deletes a farm section. Requires FARM_UPDATE permission.\nThe \"Unassigned\" section cannot be deleted." parameters: [] responses: 204: description: '' content: application/json: schema: type: object example: { } properties: { } tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: section_uuid description: '' example: 147594ba-6f75-4b06-9daf-4c9dc58b34c1 required: true schema: type: string - in: path name: company description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: section description: 'The UUID of the farm section.' example: 550e8400-e29b-41d4-a716-446655440123 required: true schema: type: string '/api/v1/c/{company_slug}/section/{section_uuid}/collectors/bulk-assign': post: summary: 'Bulk assign collectors to section' operationId: bulkAssignCollectorsToSection description: "Assigns multiple collectors to a specific farm section. The farm is derived\nfrom the section automatically. Collectors already on this farm+section are skipped.\nRequires COLLECTOR_UPDATE permission." parameters: [] responses: 200: description: '' content: text/plain: schema: type: string example: '{"data": {"assigned": 2, "skipped": 1, "collectors": [...]}}' 403: description: '' content: application/json: schema: type: object example: message: 'This action is unauthorized.' properties: message: type: string example: 'This action is unauthorized.' 404: description: '' content: application/json: schema: type: object example: error: 'Section not found' properties: error: type: string example: 'Section not found' 422: description: '' content: application/json: schema: type: object example: message: 'Validation failed' errors: collectorUuids: - 'At least one collector UUID is required' properties: message: type: string example: 'Validation failed' errors: type: object properties: collectorUuids: type: array example: - 'At least one collector UUID is required' items: type: string tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: collectorUuids: type: array description: 'List of collector UUIDs to assign.' example: - 550e8400-e29b-41d4-a716-446655440001 - 550e8400-e29b-41d4-a716-446655440002 items: type: string required: - collectorUuids parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: section_uuid description: '' example: 147594ba-6f75-4b06-9daf-4c9dc58b34c1 required: true schema: type: string - in: path name: company description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: section description: 'The UUID of the farm section.' example: 550e8400-e29b-41d4-a716-446655440123 required: true schema: type: string '/api/v1/c/{company_slug}/weather': get: summary: 'Get current weather for all farms in a company' operationId: getCurrentWeatherForAllFarmsInACompany description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string '/api/v1/c/{company_slug}/weather/farm/{farm_uuid}/current': get: summary: 'Get current weather for a specific farm' operationId: getCurrentWeatherForASpecificFarm description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: farm_uuid description: '' example: c9b4c54e-a135-4a7f-86c9-7f03b9329a1b required: true schema: type: string '/api/v1/c/{company_slug}/weather/farm/{farm_uuid}/history': get: summary: 'Get weather history for a specific farm' operationId: getWeatherHistoryForASpecificFarm description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints requestBody: required: false content: application/json: schema: type: object properties: from: type: string description: 'Start date for weather history. Must be a valid date. Must be a date before or equal to to.' example: '2025-01-01' to: type: string description: 'End date for weather history. Must be a valid date. Must be a date after or equal to from.' example: '2025-01-31' page: type: integer description: 'Page number for pagination. Must be at least 1.' example: 1 perPage: type: integer description: 'Number of records per page (max 100). Must be at least 1. Must not be greater than 100.' example: 25 limit: type: integer description: 'Must be at least 1. Must not be greater than 100.' example: 6 parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: farm_uuid description: '' example: c9b4c54e-a135-4a7f-86c9-7f03b9329a1b required: true schema: type: string '/api/v1/c/{company_slug}/weather/farm/{farm_uuid}/refresh': post: summary: 'Refresh weather data for a specific farm' operationId: refreshWeatherDataForASpecificFarm description: '' parameters: [] responses: { } tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: farm_uuid description: '' example: c9b4c54e-a135-4a7f-86c9-7f03b9329a1b required: true schema: type: string '/api/v1/c/{company_slug}/device-model-insights/{collector_uuid}': get: summary: '' operationId: getApiV1CCompany_slugDeviceModelInsightsCollector_uuid description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: collector_uuid description: '' example: aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa required: true schema: type: string '/api/v1/c/{company_slug}/firmware': get: summary: '' operationId: getApiV1CCompany_slugFirmware description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints requestBody: required: false content: application/json: schema: type: object properties: deviceModelTypeSlug: type: string description: 'Filter by device model type slug. The slug of an existing record in the device_model_types table.' example: ncu-v2 enabled: type: boolean description: 'Filter by enabled status.' example: true perPage: type: integer description: 'Number of records per page (1-100). Must be at least 1. Must not be greater than 100.' example: 25 parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string '/api/v1/c/{company_slug}/mobile/audit-events': post: summary: 'Store Mobile Audit Events' operationId: storeMobileAuditEvents description: "Upload a batch of mobile audit events for a company.\nDuplicate eventUuids are silently skipped (idempotent)." parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: deviceUuid: type: string description: 'UUID of the mobile device uploading audit events. Must be a valid UUID.' example: 550e8400-e29b-41d4-a716-446655440070 events: type: array description: 'Batch of audit events (1 to 100 items). Must have at least 1 items. Must not have more than 100 items.' example: - eventUuid: 550e8400-e29b-41d4-a716-446655440071 occurredAt: '2026-02-17T10:00:00Z' eventName: collector_connection actionName: connect operatorLabel: operator-1 connectionType: bluetooth collectorUuid: 550e8400-e29b-41d4-a716-446655440072 context: signalRssi: -64 request: source: mobile result: status: success geo: lat: 33.4484 lng: -112.074 items: type: object properties: eventUuid: type: string description: 'Must be a valid UUID.' example: 49542a53-089b-3863-bddb-01091d34d736 occurredAt: type: string description: 'Must be a valid date.' example: '2026-03-26T23:05:09' eventName: type: string description: 'The slug of an existing record in the mobile_audit_event_types table.' example: officiis actionName: type: string description: 'The slug of an existing record in the mobile_audit_action_types table.' example: pariatur operatorLabel: type: string description: 'Must not be greater than 255 characters.' example: dukqtlmwinvernr nullable: true connectionType: type: string description: '' example: sint nullable: true collectorUuid: type: string description: 'Must be a valid UUID.' example: d19db235-158b-3856-8d22-914cbf20f11a nullable: true context: type: object description: '' example: null properties: { } nullable: true request: type: object description: '' example: null properties: { } nullable: true result: type: object description: '' example: null properties: { } nullable: true geo: type: object description: '' example: null properties: lat: type: number description: 'This field is required when events.*.geo is present. Must be between -90 and 90.' example: -90 lng: type: number description: 'This field is required when events.*.geo is present. Must be between -180 and 180.' example: -179 nullable: true required: - eventUuid - occurredAt - eventName - actionName required: - deviceUuid - events parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: company description: 'The slug of the company' example: aut required: true schema: type: string '/api/v1/c/{company_slug}/mobile/ncu-data': post: summary: 'Upload NCU measurement and parameter data.' operationId: uploadNCUMeasurementAndParameterData description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: deviceUuid: type: string description: 'UUID of the mobile device sending the batch. Must be a valid UUID.' example: 550e8400-e29b-41d4-a716-446655440080 batchUuid: type: string description: 'UUID identifying this upload batch. Must be a valid UUID.' example: 550e8400-e29b-41d4-a716-446655440081 collectorUuid: type: string description: 'UUID of the collector associated with the uploaded data. Must be a valid UUID.' example: 550e8400-e29b-41d4-a716-446655440082 measurements: type: array description: 'Optional measurement entries captured in the field.' example: - timestamp: '2026-02-17T10:05:00Z' data: ambientTemp: 31.2 items: type: object nullable: true properties: timestamp: type: string description: 'Must be a valid date.' example: '2026-03-26T23:05:09' required: - timestamp parameters: type: object description: 'Optional parameter snapshots captured in the same batch.' example: firmwareVersion: 1.18.4 mode: auto properties: { } nullable: true required: - deviceUuid - batchUuid - collectorUuid parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string '/api/v1/c/{company_slug}/mobile/ncu-logs': post: summary: 'Upload NCU raw log file.' operationId: uploadNCURawLogFile description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: multipart/form-data: schema: type: object properties: deviceUuid: type: string description: 'UUID of the mobile device uploading the log file. Must be a valid UUID.' example: 550e8400-e29b-41d4-a716-446655440090 collectorUuid: type: string description: 'UUID of the collector referenced by the log. Must be a valid UUID.' example: 550e8400-e29b-41d4-a716-446655440091 logFile: type: string format: binary description: 'Log file upload (max 10MB). Must be a file. Must not be greater than 10240 kilobytes.' notes: type: string description: 'Optional operator notes for the uploaded logs. Must not be greater than 1000 characters.' example: 'Captured right after an intermittent disconnect.' nullable: true required: - deviceUuid - collectorUuid - logFile parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string /api/v1/doc-lib/sections: get: summary: 'List all enabled document library sections.' operationId: listAllEnabledDocumentLibrarySections description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints '/api/v1/doc-lib/sections/{section_uuid}/categories': get: summary: 'List all enabled categories for a section.' operationId: listAllEnabledCategoriesForASection description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints parameters: - in: path name: section_uuid description: '' example: 6218f665-ccd0-417e-917a-faecaa225bc3 required: true schema: type: string '/api/v1/doc-lib/sections/{section_uuid}/categories/{category_uuid}/documents': get: summary: 'List all enabled documents for a category.' operationId: listAllEnabledDocumentsForACategory description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints parameters: - in: path name: section_uuid description: '' example: 6218f665-ccd0-417e-917a-faecaa225bc3 required: true schema: type: string - in: path name: category_uuid description: '' example: 6d8ce9e4-ee38-432f-b75b-6834ef1d21bd required: true schema: type: string '/api/v1/doc-lib/sections/{section_uuid}/icon-link': post: summary: 'Generate signed icon URLs for a section.' operationId: generateSignedIconURLsForASection description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: false content: application/json: schema: type: object properties: expiryMinutes: type: integer description: 'Optional custom expiry time in minutes for the signed URL. Capped at the server-configured maximum for the asset type. Defaults to the server maximum if omitted. Must be at least 1.' example: 10 nullable: true parameters: - in: path name: section_uuid description: '' example: 6218f665-ccd0-417e-917a-faecaa225bc3 required: true schema: type: string '/api/v1/doc-lib/sections/{section_uuid}/categories/{category_uuid}/icon-link': post: summary: 'Generate signed icon URLs for a category.' operationId: generateSignedIconURLsForACategory description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: false content: application/json: schema: type: object properties: expiryMinutes: type: integer description: 'Optional custom expiry time in minutes for the signed URL. Capped at the server-configured maximum for the asset type. Defaults to the server maximum if omitted. Must be at least 1.' example: 10 nullable: true parameters: - in: path name: section_uuid description: '' example: 6218f665-ccd0-417e-917a-faecaa225bc3 required: true schema: type: string - in: path name: category_uuid description: '' example: 6d8ce9e4-ee38-432f-b75b-6834ef1d21bd required: true schema: type: string '/api/v1/doc-lib/documents/{documentSectionDocument_uuid}/icon-link': post: summary: 'Generate signed icon URLs for a document.' operationId: generateSignedIconURLsForADocument description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: false content: application/json: schema: type: object properties: expiryMinutes: type: integer description: 'Optional custom expiry time in minutes for the signed URL. Capped at the server-configured maximum for the asset type. Defaults to the server maximum if omitted. Must be at least 1.' example: 10 nullable: true parameters: - in: path name: documentSectionDocument_uuid description: '' example: ccee35e3-6359-4d97-80cc-bca275fc26cf required: true schema: type: string '/api/v1/doc-lib/sections/{section_uuid}/categories/{category_uuid}/documents/{documentSectionDocument_uuid}/download-link': post: summary: 'Generate a signed download URL for a document.' operationId: generateASignedDownloadURLForADocument description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: false content: application/json: schema: type: object properties: expiryMinutes: type: integer description: 'Optional custom expiry time in minutes for the signed URL. Capped at the server-configured maximum for the asset type. Defaults to the server maximum if omitted. Must be at least 1.' example: 10 nullable: true parameters: - in: path name: section_uuid description: '' example: 6218f665-ccd0-417e-917a-faecaa225bc3 required: true schema: type: string - in: path name: category_uuid description: '' example: 6d8ce9e4-ee38-432f-b75b-6834ef1d21bd required: true schema: type: string - in: path name: documentSectionDocument_uuid description: '' example: ccee35e3-6359-4d97-80cc-bca275fc26cf required: true schema: type: string /api/v1/email/resend: post: summary: '' operationId: postApiV1EmailResend description: '' parameters: [] responses: { } tags: - Endpoints '/api/v1/me/profile/picture/{format}': get: summary: 'Get Profile Picture' operationId: getProfilePicture description: "Retrieve the authenticated user's profile picture. Supports token authentication\nvia query parameter for use in image tags where Bearer tokens cannot be sent." parameters: - in: query name: token description: 'Optional Sanctum token for img src authentication.' example: 54|VYSnJgtQsXZWN45UOPc3y16VArMBQ1KM1eMdIxLR417e6478 required: false schema: type: string description: 'Optional Sanctum token for img src authentication.' example: 54|VYSnJgtQsXZWN45UOPc3y16VArMBQ1KM1eMdIxLR417e6478 responses: 200: description: '' content: text/plain: schema: type: string example: 'The image file stream' 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. 404: description: '' content: application/json: schema: type: object example: message: 'Profile picture not found.' properties: message: type: string example: 'Profile picture not found.' tags: - Endpoints parameters: - in: path name: format description: 'Optional parameter. The image format/conversion name.' required: true schema: type: string examples: omitted: summary: 'When the value is omitted' value: '' present: summary: 'When the value is present' value: square-48-webp /api/v1/me: get: summary: 'Get Current User' operationId: getCurrentUser description: "Retrieves the complete profile information for the currently authenticated user.\nThis includes personal details, contact information, profile picture URLs, and\nassigned roles. The endpoint provides a comprehensive view of the user's account\ndata and preferences.\n\nThis endpoint is commonly used after login to initialize the user's session\nwith their full profile data, or to refresh the local cache of user information." parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: uuid: 550e8400-e29b-41d4-a716-446655440000 email: john@example.com firstName: John lastName: Doe phone_number: '+1234567890' created_at: '2024-01-20T12:00:00Z' updated_at: '2024-01-20T12:00:00Z' profile_picture_url: 'https://example.com/profiles/john.jpg' roles: - user properties: data: type: object properties: uuid: type: string example: 550e8400-e29b-41d4-a716-446655440000 email: type: string example: john@example.com firstName: type: string example: John lastName: type: string example: Doe phone_number: type: string example: '+1234567890' created_at: type: string example: '2024-01-20T12:00:00Z' updated_at: type: string example: '2024-01-20T12:00:00Z' profile_picture_url: type: string example: 'https://example.com/profiles/john.jpg' roles: type: array example: - user items: type: string tags: - Endpoints /api/v1/me/check: get: summary: 'Check Authentication Status' operationId: checkAuthenticationStatus description: "Verifies if the current user has a valid authentication session. This endpoint\ncan be used by clients to validate their authentication state without making\na full profile request. It's particularly useful for SPA applications to check\nif their session is still valid." parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: success: true properties: success: type: boolean example: true 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints security: [] /api/v1/me/company: get: summary: 'Get User Companies' operationId: getUserCompanies description: 'Retrieve all companies associated with the authenticated user.' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: - slug: example-company createdAt: '2024-01-20T12:00:00Z' updatedAt: '2024-01-20T12:00:00Z' enabled: true defaultCountryIsoCode: ZA country: isoCode: ZA name: 'South Africa' emoji: πŸ‡ΏπŸ‡¦ name: 'Example Company' logoUrl: null logoThumbUrl: null logoLargeUrl: null logoUrlExpiresAt: null favicons: null links: first: 'https://api.example.com/api/v1/me/companies?page=1' last: 'https://api.example.com/api/v1/me/companies?page=1' prev: null next: null meta: total: 1 perPage: 15 currentPage: 1 lastPage: 1 from: 1 to: 1 hasMore: false path: 'https://api.example.com/api/v1/me/companies' properties: data: type: array example: - slug: example-company createdAt: '2024-01-20T12:00:00Z' updatedAt: '2024-01-20T12:00:00Z' enabled: true defaultCountryIsoCode: ZA country: isoCode: ZA name: 'South Africa' emoji: πŸ‡ΏπŸ‡¦ name: 'Example Company' logoUrl: null logoThumbUrl: null logoLargeUrl: null logoUrlExpiresAt: null favicons: null items: type: object properties: slug: type: string example: example-company createdAt: type: string example: '2024-01-20T12:00:00Z' updatedAt: type: string example: '2024-01-20T12:00:00Z' enabled: type: boolean example: true defaultCountryIsoCode: type: string example: ZA country: type: object properties: isoCode: type: string example: ZA name: type: string example: 'South Africa' emoji: type: string example: πŸ‡ΏπŸ‡¦ name: type: string example: 'Example Company' logoUrl: type: string example: null nullable: true logoThumbUrl: type: string example: null nullable: true logoLargeUrl: type: string example: null nullable: true logoUrlExpiresAt: type: string example: null nullable: true favicons: type: string example: null nullable: true links: type: object properties: first: type: string example: 'https://api.example.com/api/v1/me/companies?page=1' last: type: string example: 'https://api.example.com/api/v1/me/companies?page=1' prev: type: string example: null nullable: true next: type: string example: null nullable: true meta: type: object properties: total: type: integer example: 1 perPage: type: integer example: 15 currentPage: type: integer example: 1 lastPage: type: integer example: 1 from: type: integer example: 1 to: type: integer example: 1 hasMore: type: boolean example: false path: type: string example: 'https://api.example.com/api/v1/me/companies' tags: - Endpoints /api/v1/me/addresses: get: summary: '' operationId: getApiV1MeAddresses description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints post: summary: '' operationId: postApiV1MeAddresses description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: addressString: type: string description: 'Full address as a single string. If provided, individual address fields are not required. Must not be greater than 500 characters.' example: '123 Main St, London SW1A 1AA' addressLine1: type: string description: 'First line of the address (required if addressString not provided). Must not be greater than 255 characters.' example: '123 Main Street' city: type: string description: 'City name (required if addressString not provided). Must not be greater than 255 characters.' example: London postCode: type: string description: 'Postal code (required if addressString not provided). Must not be greater than 20 characters.' example: 'SW1A 1AA' countryIsoCode: type: string description: 'Two-letter ISO country code. The iso_code of an existing record in the countries table.' example: GB addressLine2: type: string description: 'Second line of the address. Must not be greater than 255 characters.' example: 'Apt 4B' nullable: true neighborhood: type: string description: 'Neighborhood name. Must not be greater than 255 characters.' example: Westminster nullable: true locality: type: string description: 'Locality name. Must not be greater than 255 characters.' example: 'Central London' nullable: true place: type: string description: 'Place name. Must not be greater than 255 characters.' example: 'Piccadilly Circus' nullable: true district: type: string description: 'District name. Must not be greater than 255 characters.' example: 'City of Westminster' nullable: true region: type: string description: 'Region name. Must not be greater than 255 characters.' example: 'Greater London' nullable: true location: type: object description: 'Geographic coordinates (supports both latitude/longitude and lat/long formats).' example: lat: 51.5074 long: -0.1278 properties: latitude: type: number description: 'Latitude coordinate (required if location object is provided). This field is required when location is present.' example: 51.5074 longitude: type: number description: 'Longitude coordinate (required if location object is provided). This field is required when location is present.' example: -0.1278 nullable: true required: - addressLine1 - city - postCode - countryIsoCode /api/v1/me/role: get: summary: 'Get User Roles' operationId: getUserRoles description: 'Retrieve all roles assigned to the authenticated user.' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: success: true data: acme-co: - admin - user tracklab: - tracklab-support properties: success: type: boolean example: true data: type: object properties: acme-co: type: array example: - admin - user items: type: string tracklab: type: array example: - tracklab-support items: type: string tags: - Endpoints /api/v1/me/permissions: get: summary: 'Get User Permissions' operationId: getUserPermissions description: 'Retrieve all permissions assigned to the authenticated user, grouped by company slug.' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: success: true data: acme-co: - collectors.view - collectors.update tracklab: - tracklab.users.view properties: success: type: boolean example: true data: type: object properties: acme-co: type: array example: - collectors.view - collectors.update items: type: string tracklab: type: array example: - tracklab.users.view items: type: string tags: - Endpoints /api/v1/me/realtime/bootstrap: get: summary: '' operationId: getApiV1MeRealtimeBootstrap description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints /api/v1/me/profile/picture: post: summary: 'Update Profile Picture' operationId: updateProfilePicture description: "Upload or update the user's profile picture." parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: uuid: 550e8400-e29b-41d4-a716-446655440000 email: john@example.com firstName: John lastName: Doe profile_picture_url: 'https://example.com/profiles/new-picture.jpg' updated_at: '2024-01-20T12:00:00Z' properties: data: type: object properties: uuid: type: string example: 550e8400-e29b-41d4-a716-446655440000 email: type: string example: john@example.com firstName: type: string example: John lastName: type: string example: Doe profile_picture_url: type: string example: 'https://example.com/profiles/new-picture.jpg' updated_at: type: string example: '2024-01-20T12:00:00Z' 422: description: '' content: application/json: schema: type: object example: message: 'The given data was invalid.' errors: file: - 'The file must be an image.' - 'The file failed to upload.' properties: message: type: string example: 'The given data was invalid.' errors: type: object properties: file: type: array example: - 'The file must be an image.' - 'The file failed to upload.' items: type: string tags: - Endpoints requestBody: required: true content: multipart/form-data: schema: type: object properties: file: type: string format: binary description: 'The image file to upload. Must be an image (jpeg, png, etc).' required: - file /api/v1/me/assets/signed-urls: post: summary: 'Generate Signed Asset URLs' operationId: generateSignedAssetURLs description: "Generate time-limited signed URLs for protected assets. These URLs can be\nused in img tags without requiring bearer token authentication." parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: assetType: profile_picture urls: imgUrl: 'https://example.com/api/v1/me/profile/picture/uuid/square-256-webp?expires=...' imgThumbUrl: 'https://example.com/api/v1/me/profile/picture/uuid/square-48-webp?expires=...' expiresAt: '2024-01-20T13:00:00Z' properties: data: type: object properties: assetType: type: string example: profile_picture urls: type: object properties: imgUrl: type: string example: 'https://example.com/api/v1/me/profile/picture/uuid/square-256-webp?expires=...' imgThumbUrl: type: string example: 'https://example.com/api/v1/me/profile/picture/uuid/square-48-webp?expires=...' expiresAt: type: string example: '2024-01-20T13:00:00Z' tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: assetType: type: string description: 'The type of asset. Currently supports: profile_picture.' example: profile_picture expiryMinutes: type: integer description: 'The URL expiry time in minutes (1-1440, default 60).' example: 120 required: - assetType /api/v1/me/document: post: summary: '' operationId: postApiV1MeDocument description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: documentTypeSlug: type: string description: 'Slug of the document type being uploaded. The slug of an existing record in the document_types table.' example: proof-of-address file: type: string description: 'The document file (must be an image).' example: consequatur required: - documentTypeSlug - file '/api/v1/me/document/{format}': get: summary: '' operationId: getApiV1MeDocumentFormat description: '' parameters: - in: query name: documentTypeSlug description: 'Slug of the document type to retrieve. The slug of an existing record in the document_types table.' example: proof-of-address required: true schema: type: string description: 'Slug of the document type to retrieve. The slug of an existing record in the document_types table.' example: proof-of-address responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints parameters: - in: path name: format description: '' example: libero required: true schema: type: string /api/v1/me/name: post: summary: 'Update User Name' operationId: updateUserName description: "Update the authenticated user's first and last name." parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: uuid: 550e8400-e29b-41d4-a716-446655440000 email: john@example.com firstName: John lastName: Doe updated_at: '2024-01-20T12:00:00Z' properties: data: type: object properties: uuid: type: string example: 550e8400-e29b-41d4-a716-446655440000 email: type: string example: john@example.com firstName: type: string example: John lastName: type: string example: Doe updated_at: type: string example: '2024-01-20T12:00:00Z' tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: firstName: type: string description: "The user's first name." example: John lastName: type: string description: "The user's last name." example: Doe nullable: true required: - firstName - lastName /api/v1/me/email: post: summary: 'Update User Email' operationId: updateUserEmail description: "Update the authenticated user's email address." parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: uuid: 550e8400-e29b-41d4-a716-446655440000 email: newemail@example.com firstName: John lastName: Doe updated_at: '2024-01-20T12:00:00Z' properties: data: type: object properties: uuid: type: string example: 550e8400-e29b-41d4-a716-446655440000 email: type: string example: newemail@example.com firstName: type: string example: John lastName: type: string example: Doe updated_at: type: string example: '2024-01-20T12:00:00Z' tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: email: type: string description: 'The new email address.' example: newemail@example.com required: - email /api/v1/me/phonenumber: post: summary: 'Update Phone Number' operationId: updatePhoneNumber description: "Update the authenticated user's phone number." parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: uuid: 550e8400-e29b-41d4-a716-446655440000 phone_number: '+1234567890' updated_at: '2024-01-20T12:00:00Z' properties: data: type: object properties: uuid: type: string example: 550e8400-e29b-41d4-a716-446655440000 phone_number: type: string example: '+1234567890' updated_at: type: string example: '2024-01-20T12:00:00Z' tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: countryIsoCode: type: string description: "The ISO code of the user's country." example: US phoneNumber: type: string description: 'The new phone number.' example: '+1234567890' required: - countryIsoCode - phoneNumber /api/v1/me/password: post: summary: 'Update Password' operationId: updatePassword description: "Update the authenticated user's password." parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: uuid: 550e8400-e29b-41d4-a716-446655440000 updated_at: '2024-01-20T12:00:00Z' properties: data: type: object properties: uuid: type: string example: 550e8400-e29b-41d4-a716-446655440000 updated_at: type: string example: '2024-01-20T12:00:00Z' 422: description: '' content: application/json: schema: type: object example: message: 'The given data was invalid.' errors: oldPassword: - 'The provided password is incorrect.' password: - 'The password must be at least 10 characters.' properties: message: type: string example: 'The given data was invalid.' errors: type: object properties: oldPassword: type: array example: - 'The provided password is incorrect.' items: type: string password: type: array example: - 'The password must be at least 10 characters.' items: type: string tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: oldPassword: type: string description: 'The current password.' example: currentPass123 password: type: string description: 'The new password (min 10 characters).' example: newSecurePass123! required: - oldPassword - password /api/v1/me/country/default: post: summary: 'Update Default Country' operationId: updateDefaultCountry description: "Update the authenticated user's default country." parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: uuid: 550e8400-e29b-41d4-a716-446655440000 updated_at: '2024-01-20T12:00:00Z' properties: data: type: object properties: uuid: type: string example: 550e8400-e29b-41d4-a716-446655440000 updated_at: type: string example: '2024-01-20T12:00:00Z' tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: countryIsoCode: type: string description: 'The ISO code of the country.' example: US required: - countryIsoCode /api/v1/me/company/default: post: summary: 'Update Default Company' operationId: updateDefaultCompany description: "Update the authenticated user's default company. The user must belong to\nthe target company (via user_companies relationship)." parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: uuid: 550e8400-e29b-41d4-a716-446655440000 defaultCompanySlug: acme-corp updated_at: '2024-01-20T12:00:00Z' properties: data: type: object properties: uuid: type: string example: 550e8400-e29b-41d4-a716-446655440000 defaultCompanySlug: type: string example: acme-corp updated_at: type: string example: '2024-01-20T12:00:00Z' 403: description: '' content: application/json: schema: type: object example: message: 'User does not belong to this company' properties: message: type: string example: 'User does not belong to this company' 422: description: '' content: application/json: schema: type: object example: message: 'The given data was invalid.' errors: companySlug: - 'The selected companySlug is invalid.' properties: message: type: string example: 'The given data was invalid.' errors: type: object properties: companySlug: type: array example: - 'The selected companySlug is invalid.' items: type: string tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: companySlug: type: string description: 'The slug of the company to set as default.' example: acme-corp required: - companySlug /api/v1/me/delete: post: summary: 'Delete Current User Account' operationId: deleteCurrentUserAccount description: 'Soft-delete the authenticated user and revoke all tokens.' parameters: [] responses: { } tags: - Endpoints /api/v1/me/2fa/enable: post: summary: '' operationId: postApiV1Me2faEnable description: '' parameters: [] responses: { } tags: - Endpoints /api/v1/me/2fa/verify: post: summary: '' operationId: postApiV1Me2faVerify description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: code: type: string description: 'The current two-factor authentication code.' example: '123456' required: - code /api/v1/me/2fa/disable: post: summary: '' operationId: postApiV1Me2faDisable description: '' parameters: [] responses: { } tags: - Endpoints /api/v1/me/sessions: get: summary: '' operationId: getApiV1MeSessions description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints /api/v1/me/sessions/revoke: post: summary: '' operationId: postApiV1MeSessionsRevoke description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: sessionId: type: string description: 'The UUID of the session to revoke. Must be a valid UUID.' example: 550e8400-e29b-41d4-a716-446655440000 required: - sessionId /api/v1/me/sessions/revoke-all: post: summary: '' operationId: postApiV1MeSessionsRevokeAll description: '' parameters: [] responses: { } tags: - Endpoints /api/v1/me/mobile/devices: post: summary: 'Register or Update Mobile Device' operationId: registerOrUpdateMobileDevice description: "Registers a new mobile device for the authenticated user, or updates\nan existing device if the deviceUuid already belongs to this user.\nReturns 403 if the deviceUuid belongs to a different user." parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: deviceUuid: type: string description: 'Unique identifier for the mobile device. Must be a valid UUID.' example: 550e8400-e29b-41d4-a716-446655440000 platform: type: string description: 'Mobile platform slug (android or ios).' example: android enum: - android - ios deviceModel: type: string description: 'Device hardware model name. Must not be greater than 255 characters.' example: 'Pixel 7 Pro' nullable: true osVersion: type: string description: 'Operating system version. Must not be greater than 100 characters.' example: '14.0' nullable: true appVersion: type: string description: 'Application version string. Must not be greater than 100 characters.' example: 1.0.0 nullable: true buildNumber: type: string description: 'Application build number. Must not be greater than 100 characters.' example: '42' nullable: true pushToken: type: string description: 'Push notification token (FCM or APNs). Must not be greater than 500 characters.' example: fcm-token-here nullable: true required: - deviceUuid - platform '/api/v1/me/mobile/devices/{deviceUuid}': patch: summary: 'Update Mobile Device Metadata' operationId: updateMobileDeviceMetadata description: "Updates partial metadata on an existing mobile device (appVersion,\nbuildNumber, pushToken, etc.). The device must belong to the\nauthenticated user." parameters: [] responses: { } tags: - Endpoints requestBody: required: false content: application/json: schema: type: object properties: deviceModel: type: string description: 'Device hardware model name. Must not be greater than 255 characters.' example: 'Pixel 7 Pro' nullable: true osVersion: type: string description: 'Operating system version. Must not be greater than 100 characters.' example: '14.0' nullable: true appVersion: type: string description: 'Application version string. Must not be greater than 100 characters.' example: 1.0.0 nullable: true buildNumber: type: string description: 'Application build number. Must not be greater than 100 characters.' example: '42' nullable: true pushToken: type: string description: 'Push notification token (FCM or APNs). Must not be greater than 500 characters.' example: fcm-token-here nullable: true parameters: - in: path name: deviceUuid description: '' example: cd0c5477-bb27-31be-8515-d13424e5025a required: true schema: type: string /api/v1/me/mobile/sync-status: get: summary: 'Get Sync Status' operationId: getSyncStatus description: "Returns server time, feature flags, and limits for mobile clients\nto configure their sync behavior." parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints '/api/v1/sa/c/{company_slug}/automation-rules': get: summary: '' operationId: getApiV1SaCCompany_slugAutomationRules description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints post: summary: '' operationId: postApiV1SaCCompany_slugAutomationRules description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: companySlug: type: string description: 'Company scope slug. Provide exactly one scope field. The slug of an existing record in the companies table.' example: acme-solar nullable: true farmUuid: type: string description: 'Farm scope UUID. Provide exactly one scope field. Must be a valid UUID. The uuid of an existing record in the farms table.' example: 550e8400-e29b-41d4-a716-446655440101 nullable: true collectorUuid: type: string description: 'Collector scope UUID. Provide exactly one scope field. Must be a valid UUID. The uuid of an existing record in the collectors table.' example: 550e8400-e29b-41d4-a716-446655440102 nullable: true status: type: string description: 'Automation rule status slug. The slug of an existing record in the automation_rule_status_types table.' example: enabled name: type: string description: 'Automation rule name. Must not be greater than 255 characters.' example: 'High Wind Stow Rule' description: type: string description: 'Automation rule description.' example: 'Stows trackers when wind speed exceeds threshold.' nullable: true cooldownMinutes: type: integer description: 'Cooldown between rule triggers in minutes. Must be at least 0.' example: 15 nullable: true autoClear: type: boolean description: 'Whether the rule should auto-clear.' example: true nullable: true clearAfterSeconds: type: integer description: 'Seconds after which the rule auto-clears. Must be at least 0.' example: 300 nullable: true evaluationPeriodSeconds: type: integer description: 'Evaluation period in seconds. Must be at least 0.' example: 60 nullable: true evaluationCountThreshold: type: integer description: 'Number of breaches required in the evaluation period. Must be at least 0.' example: 3 nullable: true required: - status - name parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string '/api/v1/sa/c/{company_slug}/automation-rules/{automationRule_uuid}': get: summary: '' operationId: getApiV1SaCCompany_slugAutomationRulesAutomationRule_uuid description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints put: summary: '' operationId: putApiV1SaCCompany_slugAutomationRulesAutomationRule_uuid description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: false content: application/json: schema: type: object properties: status: type: string description: 'Automation rule status slug. The slug of an existing record in the automation_rule_status_types table.' example: disabled nullable: true name: type: string description: 'Automation rule name. Must not be greater than 255 characters.' example: 'High Wind Stow Rule' nullable: true description: type: string description: 'Automation rule description.' example: 'Updated description for wind stow rule.' nullable: true cooldownMinutes: type: integer description: 'Cooldown between rule triggers in minutes. Must be at least 0.' example: 30 nullable: true autoClear: type: boolean description: 'Whether the rule should auto-clear.' example: true nullable: true clearAfterSeconds: type: integer description: 'Seconds after which the rule auto-clears. Must be at least 0.' example: 600 nullable: true evaluationPeriodSeconds: type: integer description: 'Evaluation period in seconds. Must be at least 0.' example: 120 nullable: true evaluationCountThreshold: type: integer description: 'Number of breaches required in the evaluation period. Must be at least 0.' example: 2 nullable: true delete: summary: '' operationId: deleteApiV1SaCCompany_slugAutomationRulesAutomationRule_uuid description: '' parameters: [] responses: { } tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: automationRule_uuid description: '' example: f581f30c-6b48-3a74-85e7-64bb38d7158c required: true schema: type: string '/api/v1/sa/c/{company_slug}/automation-webhook-sources': get: summary: '' operationId: getApiV1SaCCompany_slugAutomationWebhookSources description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints post: summary: '' operationId: postApiV1SaCCompany_slugAutomationWebhookSources description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: name: type: string description: 'Human-readable name for the inbound webhook source. Must not be greater than 255 characters.' example: 'Farm Weather Provider' farmUuid: type: string description: 'Optional farm UUID to scope this source to one farm. Must be a valid UUID. The uuid of an existing record in the farms table.' example: 550e8400-e29b-41d4-a716-446655440020 nullable: true required: - name parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string '/api/v1/sa/c/{company_slug}/automation-webhook-sources/{automationInboundWebhookSource_uuid}': get: summary: '' operationId: getApiV1SaCCompany_slugAutomationWebhookSourcesAutomationInboundWebhookSource_uuid description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints delete: summary: '' operationId: deleteApiV1SaCCompany_slugAutomationWebhookSourcesAutomationInboundWebhookSource_uuid description: '' parameters: [] responses: { } tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: automationInboundWebhookSource_uuid description: '' example: 82f764e1-4611-3048-b203-aa182a730f74 required: true schema: type: string '/api/v1/sa/c/{company_slug}/automation-webhook-sources/{automationInboundWebhookSource_uuid}/rotate': post: summary: '' operationId: postApiV1SaCCompany_slugAutomationWebhookSourcesAutomationInboundWebhookSource_uuidRotate description: '' parameters: [] responses: { } tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: automationInboundWebhookSource_uuid description: '' example: f467d3b6-63ea-3eb4-896f-a9c97ff6f92a required: true schema: type: string '/api/v1/sa/c/{company_slug}/automation-events': get: summary: '' operationId: getApiV1SaCCompany_slugAutomationEvents description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string '/api/v1/sa/c/{company_slug}/automation-events/{automationEvent_uuid}': get: summary: '' operationId: getApiV1SaCCompany_slugAutomationEventsAutomationEvent_uuid description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: automationEvent_uuid description: '' example: 02ccea26-141c-4f51-9aea-470b69cea45c required: true schema: type: string '/api/v1/sa/c/{company_slug}/automation-events/manual': post: summary: '' operationId: postApiV1SaCCompany_slugAutomationEventsManual description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: name: type: string description: 'The name of the manual event to fire. Must not be greater than 255 characters.' example: emergency_stow payload: type: object description: 'Optional payload data for the event.' example: reason: high_wind speed: 75 properties: { } nullable: true collectorUuid: type: string description: 'Optional collector UUID to scope the event. Must be a valid UUID.' example: 550e8400-e29b-41d4-a716-446655440001 nullable: true farmUuid: type: string description: 'Optional farm UUID to scope the event. Must be a valid UUID.' example: 550e8400-e29b-41d4-a716-446655440002 nullable: true required: - name parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string '/api/v1/sa/c/{company_slug}/automation-executions': get: summary: '' operationId: getApiV1SaCCompany_slugAutomationExecutions description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string '/api/v1/sa/c/{company_slug}/automation-executions/{automationExecution_uuid}': get: summary: '' operationId: getApiV1SaCCompany_slugAutomationExecutionsAutomationExecution_uuid description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: automationExecution_uuid description: '' example: 31e0f72f-9c0b-3245-8bb1-c802bfc06535 required: true schema: type: string '/api/v1/sa/c/{company_slug}/automation/test/fire-event': post: summary: '' operationId: postApiV1SaCCompany_slugAutomationTestFireEvent description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: name: type: string description: 'Automation event name to fire. Must not be greater than 255 characters.' example: manual_stow_triggered payload: type: object description: 'Optional payload delivered with the event.' example: reason: high_wind windSpeed: 21.6 properties: { } nullable: true farmUuid: type: string description: 'Optional farm UUID to scope the event. Must be a valid UUID.' example: 550e8400-e29b-41d4-a716-446655440040 nullable: true collectorUuid: type: string description: 'Optional collector UUID to scope the event. Must be a valid UUID.' example: 550e8400-e29b-41d4-a716-446655440041 nullable: true required: - name parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string '/api/v1/sa/c/{company_slug}/automation/test/dry-run-match': post: summary: '' operationId: postApiV1SaCCompany_slugAutomationTestDryRunMatch description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: ruleUuid: type: string description: 'UUID of the automation rule to evaluate. Must be a valid UUID. The uuid of an existing record in the automation_rules table.' example: 550e8400-e29b-41d4-a716-446655440030 eventPayload: type: object description: 'Event payload to run against rule conditions without executing actions.' example: eventName: wind_alert speed: 72.4 unit: kmh properties: { } required: - ruleUuid - eventPayload parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string '/api/v1/sa/c/{company_slug}/automation/test/preview-template': post: summary: '' operationId: postApiV1SaCCompany_slugAutomationTestPreviewTemplate description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: template: type: string description: 'Template string to preview.' example: 'Alert: @{{ collector.name }} exceeded @{{ threshold }}.' context: type: object description: 'Template context data used for placeholder replacement.' example: collector: name: NCU-12 threshold: 85 properties: { } required: - template - context parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string '/api/v1/sa/c/{company_slug}/automation/test/send-notification': post: summary: '' operationId: postApiV1SaCCompany_slugAutomationTestSendNotification description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: notificationPolicyUuid: type: string description: 'UUID of the notification policy used for this test send. Must be a valid UUID. The uuid of an existing record in the notification_policies table.' example: 550e8400-e29b-41d4-a716-446655440050 recipientEmail: type: string description: 'Recipient email address for the test notification. Must be a valid email address.' example: alerts@example.com context: type: object description: 'Optional context payload rendered in the notification template.' example: collectorName: NCU-5 alarm: overheat properties: { } nullable: true required: - notificationPolicyUuid - recipientEmail parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string '/api/v1/sa/c/{company_slug}/automation/test/webhook-endpoints': get: summary: '' operationId: getApiV1SaCCompany_slugAutomationTestWebhookEndpoints description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints post: summary: '' operationId: postApiV1SaCCompany_slugAutomationTestWebhookEndpoints description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: name: type: string description: 'Unique endpoint name within the company. Must not be greater than 255 characters.' example: weather-station-test-endpoint required: - name parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string '/api/v1/sa/c/{company_slug}/automation/test/webhook-endpoints/{automationTestWebhookEndpoint_uuid}': get: summary: '' operationId: getApiV1SaCCompany_slugAutomationTestWebhookEndpointsAutomationTestWebhookEndpoint_uuid description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints put: summary: '' operationId: putApiV1SaCCompany_slugAutomationTestWebhookEndpointsAutomationTestWebhookEndpoint_uuid description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: enabled: type: boolean description: 'Whether this test webhook endpoint is enabled.' example: true required: - enabled delete: summary: '' operationId: deleteApiV1SaCCompany_slugAutomationTestWebhookEndpointsAutomationTestWebhookEndpoint_uuid description: '' parameters: [] responses: { } tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: automationTestWebhookEndpoint_uuid description: '' example: b08e44f2-9bb2-38f6-82cb-663878dc1782 required: true schema: type: string '/api/v1/sa/c/{company_slug}/automation/test/webhook-endpoints/{automationTestWebhookEndpoint_uuid}/rotate': post: summary: '' operationId: postApiV1SaCCompany_slugAutomationTestWebhookEndpointsAutomationTestWebhookEndpoint_uuidRotate description: '' parameters: [] responses: { } tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: automationTestWebhookEndpoint_uuid description: '' example: efd2d379-3e27-3497-acb9-530dc08d9e3b required: true schema: type: string '/api/v1/sa/c/{company_slug}/automation/test/webhook-endpoints/{automationTestWebhookEndpoint_uuid}/events': get: summary: '' operationId: getApiV1SaCCompany_slugAutomationTestWebhookEndpointsAutomationTestWebhookEndpoint_uuidEvents description: '' parameters: - in: query name: perPage description: 'Number of events to return per page. Must be at least 1. Must not be greater than 100.' example: 25 required: false schema: type: integer description: 'Number of events to return per page. Must be at least 1. Must not be greater than 100.' example: 25 nullable: true - in: query name: page description: 'Pagination page number. Must be at least 1.' example: 1 required: false schema: type: integer description: 'Pagination page number. Must be at least 1.' example: 1 nullable: true responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints delete: summary: '' operationId: deleteApiV1SaCCompany_slugAutomationTestWebhookEndpointsAutomationTestWebhookEndpoint_uuidEvents description: '' parameters: [] responses: { } tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: automationTestWebhookEndpoint_uuid description: '' example: 9523d35d-71d3-35e6-89dd-6e87c1e440dc required: true schema: type: string '/api/v1/sa/c/{company_slug}/automation/test/webhook-endpoints/{automationTestWebhookEndpoint_uuid}/events/latest': get: summary: '' operationId: getApiV1SaCCompany_slugAutomationTestWebhookEndpointsAutomationTestWebhookEndpoint_uuidEventsLatest description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: automationTestWebhookEndpoint_uuid description: '' example: c9494408-88bf-340b-a9d0-d71145e7f42e required: true schema: type: string '/api/v1/sa/c/{company_slug}/automation/test/webhook-events/{automationTestWebhookEvent_uuid}': get: summary: '' operationId: getApiV1SaCCompany_slugAutomationTestWebhookEventsAutomationTestWebhookEvent_uuid description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints delete: summary: '' operationId: deleteApiV1SaCCompany_slugAutomationTestWebhookEventsAutomationTestWebhookEvent_uuid description: '' parameters: [] responses: { } tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: automationTestWebhookEvent_uuid description: '' example: 396228d8-5c65-3b7b-8655-6c8e2c49392f required: true schema: type: string '/api/v1/sa/c/{company_slug}/automation/test/webhook-inbox/setup': post: summary: '' operationId: postApiV1SaCCompany_slugAutomationTestWebhookInboxSetup description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: false content: application/json: schema: type: object properties: name: type: string description: 'Optional display name for the webhook inbox endpoint. Must not be greater than 255 characters.' example: 'Automation Test Inbox' nullable: true resetEvents: type: boolean description: 'Whether to clear existing captured webhook events before setup.' example: false nullable: true rotateSecret: type: boolean description: 'Whether to rotate the endpoint secret during setup.' example: true nullable: true notificationChannelUuid: type: string description: 'Optional notification channel UUID to connect with this inbox. Must be a valid UUID. The uuid of an existing record in the notification_channels table.' example: 550e8400-e29b-41d4-a716-446655440010 nullable: true parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string /api/v1/sa/collectors: get: summary: '' operationId: getApiV1SaCollectors description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints post: summary: '' operationId: postApiV1SaCollectors description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: name: type: string description: 'Collector name. Must not be greater than 255 characters.' example: NCU-001 description: type: string description: 'Collector description. Must not be greater than 255 characters.' example: 'Main control unit for section A' nullable: true collectorTypeSlug: type: string description: 'Collector type identifier (slug). Allowed: ncu, tcu.' example: ncu enum: - ncu - tcu farmSectionUuid: type: string description: 'UUID of the farm section (required, determines farm and company). Must be a valid UUID. The uuid of an existing record in the farm_sections table.' example: 550e8400-e29b-41d4-a716-446655440123 serial: type: string description: 'Unique serial number. Must not be greater than 255 characters.' example: NCU-2025-001234 enabled: type: boolean description: 'Whether the collector is enabled.' example: true locationJson: type: object description: 'Geographic location.' example: latitude: -33.8688 longitude: 151.2093 properties: latitude: type: number description: 'This field is required when locationJson is present. Must be between -90 and 90.' example: -33.8688 longitude: type: number description: 'This field is required when locationJson is present. Must be between -180 and 180.' example: 151.2093 nullable: true parentUuid: type: string description: 'UUID of the parent NCU (required for TCU, must belong to same company). Must be a valid UUID. The uuid of an existing record in the collectors table.' example: 550e8400-e29b-41d4-a716-446655440001 required: - name - collectorTypeSlug - farmSectionUuid - serial /api/v1/sa/collectors/summary: get: summary: '' operationId: getApiV1SaCollectorsSummary description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints /api/v1/sa/collectors/register: post: summary: '' operationId: postApiV1SaCollectorsRegister description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: serial: type: string description: 'Unique serial number for the collector. Must not be greater than 255 characters.' example: NCU-2025-001234 deviceModelTypeSlug: type: string description: 'Device model type slug. The slug of an existing record in the device_model_types table.' example: ncu-x100-001 hardwareVersionTypeSlug: type: string description: 'Hardware version type slug (optional). The slug of an existing record in the hardware_version_types table.' example: v1-0-0 nullable: true manufacturedAt: type: string description: 'Manufacture date (optional). Must be a valid date.' example: '2025-01-15' nullable: true required: - serial - deviceModelTypeSlug /api/v1/sa/collectors/bulk-register: post: summary: '' operationId: postApiV1SaCollectorsBulkRegister description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: devices: type: array description: 'Array of devices to register (max 500). Must have at least 1 items. Must not have more than 500 items.' example: - serial: NCU-2025-001234 deviceModelTypeSlug: ncu-x100-001 hardwareVersionTypeSlug: v1-0-0 manufacturedAt: '2025-01-15' items: type: object properties: serial: type: string description: 'Must not be greater than 255 characters.' example: fjfzfdbrxw deviceModelTypeSlug: type: string description: 'The slug of an existing record in the device_model_types table.' example: itaque hardwareVersionTypeSlug: type: string description: 'The slug of an existing record in the hardware_version_types table.' example: beatae nullable: true manufacturedAt: type: string description: 'Must be a valid date.' example: '2026-03-26T23:05:09' nullable: true required: - serial - deviceModelTypeSlug required: - devices '/api/v1/sa/collectors/{uuid}': get: summary: '' operationId: getApiV1SaCollectorsUuid description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints patch: summary: '' operationId: patchApiV1SaCollectorsUuid description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: name: type: string description: 'Collector name. Must not be greater than 255 characters.' example: 'NCU-001 Updated' description: type: string description: 'Collector description. Must not be greater than 255 characters.' example: 'Updated control unit for section A' nullable: true collectorTypeSlug: type: string description: 'Collector type identifier (slug). Allowed: ncu, tcu.' example: tcu enum: - ncu - tcu farmSectionUuid: type: string description: 'UUID of the farm section (required, determines farm and company). Must be a valid UUID. The uuid of an existing record in the farm_sections table.' example: 550e8400-e29b-41d4-a716-446655440123 serial: type: string description: 'Unique serial number. Must not be greater than 255 characters.' example: NCU-2025-001234 enabled: type: boolean description: 'Whether the collector is enabled.' example: true locationJson: type: object description: 'Geographic location.' example: latitude: -33.8688 longitude: 151.2093 properties: latitude: type: number description: 'This field is required when locationJson is present. Must be between -90 and 90.' example: -33.8688 longitude: type: number description: 'This field is required when locationJson is present. Must be between -180 and 180.' example: 151.2093 nullable: true parentUuid: type: string description: 'UUID of the parent collector. Must be a valid UUID. The uuid of an existing record in the collectors table.' example: 550e8400-e29b-41d4-a716-446655440001 nullable: true required: - name - collectorTypeSlug - farmSectionUuid - serial delete: summary: '' operationId: deleteApiV1SaCollectorsUuid description: '' parameters: [] responses: { } tags: - Endpoints parameters: - in: path name: uuid description: '' example: aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa required: true schema: type: string '/api/v1/sa/collectors/{collector_uuid}/status-history': get: summary: '' operationId: getApiV1SaCollectorsCollector_uuidStatusHistory description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints parameters: - in: path name: collector_uuid description: '' example: aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa required: true schema: type: string '/api/v1/sa/collectors/{collector_uuid}/status': patch: summary: '' operationId: patchApiV1SaCollectorsCollector_uuidStatus description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: status: type: string description: 'Target status slug to transition to. The slug of an existing record in the collector_status_types table.' example: testing reason: type: string description: 'Optional reason for the status transition. Must not be greater than 1000 characters.' example: 'Moving to testing phase after QA review' nullable: true required: - status parameters: - in: path name: collector_uuid description: '' example: aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa required: true schema: type: string '/api/v1/sa/collectors/{collector_uuid}/timeline': get: summary: '' operationId: getApiV1SaCollectorsCollector_uuidTimeline description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints parameters: - in: path name: collector_uuid description: '' example: aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa required: true schema: type: string '/api/v1/sa/collectors/{collector_uuid}/transfer': put: summary: '' operationId: putApiV1SaCollectorsCollector_uuidTransfer description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: targetCompanySlug: type: string description: 'Slug of the target company to transfer the collector to. The slug of an existing record in the companies table.' example: acme-solar reason: type: string description: 'Reason for the transfer. Must not be greater than 2000 characters.' example: 'Customer contract change' nullable: true required: - targetCompanySlug parameters: - in: path name: collector_uuid description: '' example: aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa required: true schema: type: string /api/v1/sa/unassigned-collectors: get: summary: '' operationId: getApiV1SaUnassignedCollectors description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints '/api/v1/sa/collectors/{collector_uuid}/assign': post: summary: '' operationId: postApiV1SaCollectorsCollector_uuidAssign description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: parentCollectorUuid: type: string description: 'UUID of the parent collector to assign. Must be a valid UUID. The uuid of an existing record in the collectors table.' example: 550e8400-e29b-41d4-a716-446655440321 required: - parentCollectorUuid parameters: - in: path name: collector_uuid description: '' example: aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa required: true schema: type: string '/api/v1/sa/collectors/{collector_uuid}/unlink': post: summary: '' operationId: postApiV1SaCollectorsCollector_uuidUnlink description: '' parameters: [] responses: { } tags: - Endpoints parameters: - in: path name: collector_uuid description: '' example: aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa required: true schema: type: string '/api/v1/sa/collectors/{collector_uuid}/change-type': patch: summary: '' operationId: patchApiV1SaCollectorsCollector_uuidChangeType description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: collectorTypeSlug: type: string description: 'Collector type slug to assign. The slug of an existing record in the collector_types table.' example: tcu required: - collectorTypeSlug parameters: - in: path name: collector_uuid description: '' example: aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa required: true schema: type: string '/api/v1/sa/collectors/{collector_uuid}/warranty': post: summary: 'Assign a warranty to a collector.' operationId: assignAWarrantyToACollector description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: warrantyTypeSlug: type: string description: 'Warranty type slug to assign. The slug of an existing record in the warranty_types table.' example: standard-two-year warrantyStart: type: string description: 'Warranty start date. Must be a valid date.' example: '2026-02-17' warrantyEnd: type: string description: 'Optional warranty end date. Must be after warrantyStart. Must be a valid date. Must be a date after warrantyStart.' example: '2028-02-17' nullable: true notes: type: string description: 'Optional notes associated with this warranty assignment. Must not be greater than 2000 characters.' example: 'Coverage includes actuator and controller board.' nullable: true required: - warrantyTypeSlug - warrantyStart parameters: - in: path name: collector_uuid description: '' example: aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa required: true schema: type: string /api/v1/sa/farms: get: summary: '' operationId: getApiV1SaFarms description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints post: summary: '' operationId: postApiV1SaFarms description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: name: type: string description: 'Farm name. Must not be greater than 255 characters.' example: 'Solar Farm Alpha' description: type: string description: 'Farm description. Must not be greater than 255 characters.' example: 'Main solar installation in the northern region' nullable: true companySlug: type: string description: 'Company identifier (slug). The slug of an existing record in the companies table.' example: solar-energy-corp locationJson: type: object description: 'Geographic location with latitude and longitude.' example: latitude: -33.8688 longitude: 151.2093 properties: latitude: type: number description: 'Must be between -90 and 90.' example: -33.8688 longitude: type: number description: 'Must be between -180 and 180.' example: 151.2093 required: - latitude - longitude enabled: type: boolean description: 'Whether the farm is enabled.' example: true required: - name - companySlug - locationJson '/api/v1/sa/farms/{uuid}': get: summary: '' operationId: getApiV1SaFarmsUuid description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints patch: summary: '' operationId: patchApiV1SaFarmsUuid description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: name: type: string description: 'Farm name. Must not be greater than 255 characters.' example: 'Solar Farm Alpha Updated' description: type: string description: 'Farm description. Must not be greater than 255 characters.' example: 'Updated solar installation details' nullable: true companySlug: type: string description: '' example: null locationJson: type: object description: 'Geographic location with latitude and longitude.' example: latitude: -33.8688 longitude: 151.2093 properties: latitude: type: number description: 'This field is required when locationJson is present. Must be between -90 and 90.' example: -33.8688 longitude: type: number description: 'This field is required when locationJson is present. Must be between -180 and 180.' example: 151.2093 nullable: true enabled: type: boolean description: 'Whether the farm is enabled.' example: true required: - name delete: summary: '' operationId: deleteApiV1SaFarmsUuid description: '' parameters: [] responses: { } tags: - Endpoints parameters: - in: path name: uuid description: '' example: c9b4c54e-a135-4a7f-86c9-7f03b9329a1b required: true schema: type: string '/api/v1/sa/farms/{farm_uuid}/collectors/bulk-assign': post: summary: 'Bulk assign collectors to a farm' operationId: bulkAssignCollectorsToAFarm description: "Assign multiple collectors to a farm in a single request.\nCollectors must belong to the same company as the farm." parameters: [] responses: 200: description: '' content: text/plain: schema: type: string example: "{\n \"success\": true,\n \"message\": \"Assigned 5 collector(s) to farm\",\n \"data\": {\n \"assigned\": 5,\n \"skipped\": 2,\n \"collectors\": [...]\n }\n}" tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: collectorUuids: type: array description: 'List of collector UUIDs to assign.' example: - 550e8400-e29b-41d4-a716-446655440001 - 550e8400-e29b-41d4-a716-446655440002 items: type: string required: - collectorUuids parameters: - in: path name: farm_uuid description: '' example: c9b4c54e-a135-4a7f-86c9-7f03b9329a1b required: true schema: type: string - in: path name: farm description: 'The UUID of the farm.' example: 550e8400-e29b-41d4-a716-446655440000 required: true schema: type: string '/api/v1/sa/farms/{farm_uuid}/sections': get: summary: 'List sections for a farm' operationId: listSectionsForAFarm description: '' parameters: - in: query name: enabled_only description: 'Filter to only enabled sections.' example: true required: false schema: type: boolean description: 'Filter to only enabled sections.' example: true - in: query name: page description: 'Page number.' example: 1 required: false schema: type: integer description: 'Page number.' example: 1 - in: query name: perPage description: 'Results per page (max 100).' example: 25 required: false schema: type: integer description: 'Results per page (max 100).' example: 25 responses: 200: description: '' content: application/json: schema: type: object example: data: - uuid: 147594ba-6f75-4b06-9daf-4c9dc58b34c1 name: Unassigned description: '' enabled: true orderColumn: 0 location: null locationJson: null metadata: null createdAt: '2026-01-14T19:48:46+00:00' updatedAt: '2026-01-16T10:41:36+00:00' isUnassigned: true - uuid: 147594ba-6f75-4b06-9daf-4c9dc58b34c1 name: Unassigned description: '' enabled: true orderColumn: 0 location: null locationJson: null metadata: null createdAt: '2026-01-14T19:48:46+00:00' updatedAt: '2026-01-16T10:41:36+00:00' isUnassigned: true properties: data: type: array example: - uuid: 147594ba-6f75-4b06-9daf-4c9dc58b34c1 name: Unassigned description: '' enabled: true orderColumn: 0 location: null locationJson: null metadata: null createdAt: '2026-01-14T19:48:46+00:00' updatedAt: '2026-01-16T10:41:36+00:00' isUnassigned: true - uuid: 147594ba-6f75-4b06-9daf-4c9dc58b34c1 name: Unassigned description: '' enabled: true orderColumn: 0 location: null locationJson: null metadata: null createdAt: '2026-01-14T19:48:46+00:00' updatedAt: '2026-01-16T10:41:36+00:00' isUnassigned: true items: type: object properties: uuid: type: string example: 147594ba-6f75-4b06-9daf-4c9dc58b34c1 name: type: string example: Unassigned description: type: string example: '' enabled: type: boolean example: true orderColumn: type: integer example: 0 location: type: string example: null nullable: true locationJson: type: string example: null nullable: true metadata: type: string example: null nullable: true createdAt: type: string example: '2026-01-14T19:48:46+00:00' updatedAt: type: string example: '2026-01-16T10:41:36+00:00' isUnassigned: type: boolean example: true tags: - Endpoints post: summary: 'Create a new farm section' operationId: createANewFarmSection description: '' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: uuid: 147594ba-6f75-4b06-9daf-4c9dc58b34c1 name: Unassigned description: '' enabled: true orderColumn: 0 location: null locationJson: null metadata: null createdAt: '2026-01-14T19:48:46+00:00' updatedAt: '2026-01-16T10:41:36+00:00' isUnassigned: true properties: data: type: object properties: uuid: type: string example: 147594ba-6f75-4b06-9daf-4c9dc58b34c1 name: type: string example: Unassigned description: type: string example: '' enabled: type: boolean example: true orderColumn: type: integer example: 0 location: type: string example: null nullable: true locationJson: type: string example: null nullable: true metadata: type: string example: null nullable: true createdAt: type: string example: '2026-01-14T19:48:46+00:00' updatedAt: type: string example: '2026-01-16T10:41:36+00:00' isUnassigned: type: boolean example: true tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: name: type: string description: 'The name of the section.' example: 'North Field' slug: type: string description: '' example: null description: type: string description: 'The description.' example: 'Northern section of the farm' nullable: true enabled: type: boolean description: 'Whether section is enabled.' example: true orderColumn: type: integer description: 'Display order.' example: 1 locationJson: type: object description: 'Location coordinates.' example: latitude: 51.509865 longitude: -0.118092 properties: latitude: type: number description: 'This field is required when locationJson is present. Must be between -90 and 90.' example: 51.509865 longitude: type: number description: 'This field is required when locationJson is present. Must be between -180 and 180.' example: -0.118092 nullable: true metadata: type: object description: 'Optional metadata.' example: notes: 'Primary section' properties: { } nullable: true required: - name parameters: - in: path name: farm_uuid description: '' example: c9b4c54e-a135-4a7f-86c9-7f03b9329a1b required: true schema: type: string - in: path name: farm description: 'The UUID of the farm' example: est required: true schema: type: string '/api/v1/sa/farm-sections/{section_uuid}': get: summary: 'Show a farm section' operationId: showAFarmSection description: '' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: uuid: 147594ba-6f75-4b06-9daf-4c9dc58b34c1 name: Unassigned description: '' enabled: true orderColumn: 0 location: null locationJson: null metadata: null createdAt: '2026-01-14T19:48:46+00:00' updatedAt: '2026-01-16T10:41:36+00:00' isUnassigned: true properties: data: type: object properties: uuid: type: string example: 147594ba-6f75-4b06-9daf-4c9dc58b34c1 name: type: string example: Unassigned description: type: string example: '' enabled: type: boolean example: true orderColumn: type: integer example: 0 location: type: string example: null nullable: true locationJson: type: string example: null nullable: true metadata: type: string example: null nullable: true createdAt: type: string example: '2026-01-14T19:48:46+00:00' updatedAt: type: string example: '2026-01-16T10:41:36+00:00' isUnassigned: type: boolean example: true tags: - Endpoints patch: summary: 'Update a farm section' operationId: updateAFarmSection description: '' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: uuid: 147594ba-6f75-4b06-9daf-4c9dc58b34c1 name: Unassigned description: '' enabled: true orderColumn: 0 location: null locationJson: null metadata: null createdAt: '2026-01-14T19:48:46+00:00' updatedAt: '2026-01-16T10:41:36+00:00' isUnassigned: true properties: data: type: object properties: uuid: type: string example: 147594ba-6f75-4b06-9daf-4c9dc58b34c1 name: type: string example: Unassigned description: type: string example: '' enabled: type: boolean example: true orderColumn: type: integer example: 0 location: type: string example: null nullable: true locationJson: type: string example: null nullable: true metadata: type: string example: null nullable: true createdAt: type: string example: '2026-01-14T19:48:46+00:00' updatedAt: type: string example: '2026-01-16T10:41:36+00:00' isUnassigned: type: boolean example: true tags: - Endpoints requestBody: required: false content: application/json: schema: type: object properties: name: type: string description: 'The name of the section.' example: 'North Field Updated' slug: type: string description: '' example: null description: type: string description: 'The description.' example: 'Updated description' nullable: true enabled: type: boolean description: 'Whether section is enabled.' example: false orderColumn: type: integer description: 'Display order.' example: 2 locationJson: type: object description: 'Location coordinates.' example: latitude: 51.509865 longitude: -0.118092 properties: latitude: type: number description: 'This field is required when locationJson is present. Must be between -90 and 90.' example: 51.509865 longitude: type: number description: 'This field is required when locationJson is present. Must be between -180 and 180.' example: -0.118092 nullable: true metadata: type: object description: 'Optional metadata.' example: notes: 'Updated notes' properties: { } nullable: true delete: summary: 'Delete a farm section' operationId: deleteAFarmSection description: '' parameters: [] responses: 204: description: '' content: application/json: schema: type: object example: { } properties: { } tags: - Endpoints parameters: - in: path name: section_uuid description: '' example: 147594ba-6f75-4b06-9daf-4c9dc58b34c1 required: true schema: type: string - in: path name: section description: 'The UUID of the section' example: voluptas required: true schema: type: string '/api/v1/sa/farm-sections/{section_uuid}/collectors/bulk-assign': post: summary: 'Bulk assign collectors to section' operationId: bulkAssignCollectorsToSection description: "Assigns multiple collectors to a specific farm section. The farm is derived\nfrom the section automatically. Collectors already on this farm+section are skipped." parameters: [] responses: 200: description: '' content: text/plain: schema: type: string example: '{"data": {"assigned": 2, "skipped": 1, "collectors": [...]}}' 404: description: '' content: application/json: schema: type: object example: error: 'Section not found' properties: error: type: string example: 'Section not found' 422: description: '' content: application/json: schema: type: object example: message: 'Validation failed' errors: collectorUuids: - 'At least one collector UUID is required' properties: message: type: string example: 'Validation failed' errors: type: object properties: collectorUuids: type: array example: - 'At least one collector UUID is required' items: type: string tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: collectorUuids: type: array description: 'List of collector UUIDs to assign.' example: - 550e8400-e29b-41d4-a716-446655440001 - 550e8400-e29b-41d4-a716-446655440002 items: type: string required: - collectorUuids parameters: - in: path name: section_uuid description: '' example: 147594ba-6f75-4b06-9daf-4c9dc58b34c1 required: true schema: type: string - in: path name: section description: 'The UUID of the farm section.' example: 550e8400-e29b-41d4-a716-446655440123 required: true schema: type: string '/api/v1/sa/farms/{farm_uuid}/trackers': get: summary: 'List trackers for a farm' operationId: listTrackersForAFarm description: '' parameters: - in: query name: sectionUuid description: 'Filter by section UUID.' example: 550e8400-e29b-41d4-a716-446655440001 required: false schema: type: string description: 'Filter by section UUID.' example: 550e8400-e29b-41d4-a716-446655440001 - in: query name: isCurrent description: 'Filter by current status.' example: true required: false schema: type: boolean description: 'Filter by current status.' example: true - in: query name: placed description: 'Filter by placement status.' example: true required: false schema: type: boolean description: 'Filter by placement status.' example: true - in: query name: sectioned description: 'Filter by section assignment.' example: true required: false schema: type: boolean description: 'Filter by section assignment.' example: true - in: query name: perPage description: 'Results per page (max 200).' example: 50 required: false schema: type: integer description: 'Results per page (max 200).' example: 50 responses: 200: description: '' content: application/json: schema: type: object example: data: - uuid: a205ee53-a5ce-4ecf-8103-d1ace6488432 collectorUuid: a5ed3d06-9ac9-4eaf-8ea3-c7ec9dcafe54 collectorType: TCU farmUuid: null farmSectionUuid: 9d97ca6c-31f2-45e3-a586-2656291af1eb row: 0 column: 0 widthM: '5.00' heightM: '2.00' angleDeg: '0.00' location: null locationJson: null metadata: null isCurrent: false activeFrom: '2026-01-14T20:08:43+00:00' activeTo: '2026-03-10T09:42:17+00:00' createdAt: '2026-01-14T20:08:43+00:00' updatedAt: '2026-03-10T09:42:17+00:00' collector: uuid: a5ed3d06-9ac9-4eaf-8ea3-c7ec9dcafe54 collectorTypeSlug: tcu serial: '9' name: 'Auto-created TCU Collector 9' enabled: true farmSection: uuid: 9d97ca6c-31f2-45e3-a586-2656291af1eb name: Section1 description: '' enabled: true orderColumn: 0 location: lat: -25.860111769169364 lng: 28.194855451583862 locationJson: latitude: -25.860111769169364 longitude: 28.194855451583862 metadata: null createdAt: '2025-12-17T18:48:47+00:00' updatedAt: '2026-02-08T10:22:07+00:00' isUnassigned: false - uuid: a205ee53-a5ce-4ecf-8103-d1ace6488432 collectorUuid: a5ed3d06-9ac9-4eaf-8ea3-c7ec9dcafe54 collectorType: TCU farmUuid: null farmSectionUuid: 9d97ca6c-31f2-45e3-a586-2656291af1eb row: 0 column: 0 widthM: '5.00' heightM: '2.00' angleDeg: '0.00' location: null locationJson: null metadata: null isCurrent: false activeFrom: '2026-01-14T20:08:43+00:00' activeTo: '2026-03-10T09:42:17+00:00' createdAt: '2026-01-14T20:08:43+00:00' updatedAt: '2026-03-10T09:42:17+00:00' collector: uuid: a5ed3d06-9ac9-4eaf-8ea3-c7ec9dcafe54 collectorTypeSlug: tcu serial: '9' name: 'Auto-created TCU Collector 9' enabled: true farmSection: uuid: 9d97ca6c-31f2-45e3-a586-2656291af1eb name: Section1 description: '' enabled: true orderColumn: 0 location: lat: -25.860111769169364 lng: 28.194855451583862 locationJson: latitude: -25.860111769169364 longitude: 28.194855451583862 metadata: null createdAt: '2025-12-17T18:48:47+00:00' updatedAt: '2026-02-08T10:22:07+00:00' isUnassigned: false properties: data: type: array example: - uuid: a205ee53-a5ce-4ecf-8103-d1ace6488432 collectorUuid: a5ed3d06-9ac9-4eaf-8ea3-c7ec9dcafe54 collectorType: TCU farmUuid: null farmSectionUuid: 9d97ca6c-31f2-45e3-a586-2656291af1eb row: 0 column: 0 widthM: '5.00' heightM: '2.00' angleDeg: '0.00' location: null locationJson: null metadata: null isCurrent: false activeFrom: '2026-01-14T20:08:43+00:00' activeTo: '2026-03-10T09:42:17+00:00' createdAt: '2026-01-14T20:08:43+00:00' updatedAt: '2026-03-10T09:42:17+00:00' collector: uuid: a5ed3d06-9ac9-4eaf-8ea3-c7ec9dcafe54 collectorTypeSlug: tcu serial: '9' name: 'Auto-created TCU Collector 9' enabled: true farmSection: uuid: 9d97ca6c-31f2-45e3-a586-2656291af1eb name: Section1 description: '' enabled: true orderColumn: 0 location: lat: -25.860111769169364 lng: 28.194855451583862 locationJson: latitude: -25.860111769169364 longitude: 28.194855451583862 metadata: null createdAt: '2025-12-17T18:48:47+00:00' updatedAt: '2026-02-08T10:22:07+00:00' isUnassigned: false - uuid: a205ee53-a5ce-4ecf-8103-d1ace6488432 collectorUuid: a5ed3d06-9ac9-4eaf-8ea3-c7ec9dcafe54 collectorType: TCU farmUuid: null farmSectionUuid: 9d97ca6c-31f2-45e3-a586-2656291af1eb row: 0 column: 0 widthM: '5.00' heightM: '2.00' angleDeg: '0.00' location: null locationJson: null metadata: null isCurrent: false activeFrom: '2026-01-14T20:08:43+00:00' activeTo: '2026-03-10T09:42:17+00:00' createdAt: '2026-01-14T20:08:43+00:00' updatedAt: '2026-03-10T09:42:17+00:00' collector: uuid: a5ed3d06-9ac9-4eaf-8ea3-c7ec9dcafe54 collectorTypeSlug: tcu serial: '9' name: 'Auto-created TCU Collector 9' enabled: true farmSection: uuid: 9d97ca6c-31f2-45e3-a586-2656291af1eb name: Section1 description: '' enabled: true orderColumn: 0 location: lat: -25.860111769169364 lng: 28.194855451583862 locationJson: latitude: -25.860111769169364 longitude: 28.194855451583862 metadata: null createdAt: '2025-12-17T18:48:47+00:00' updatedAt: '2026-02-08T10:22:07+00:00' isUnassigned: false items: type: object properties: uuid: type: string example: a205ee53-a5ce-4ecf-8103-d1ace6488432 collectorUuid: type: string example: a5ed3d06-9ac9-4eaf-8ea3-c7ec9dcafe54 collectorType: type: string example: TCU farmUuid: type: string example: null nullable: true farmSectionUuid: type: string example: 9d97ca6c-31f2-45e3-a586-2656291af1eb row: type: integer example: 0 column: type: integer example: 0 widthM: type: string example: '5.00' heightM: type: string example: '2.00' angleDeg: type: string example: '0.00' location: type: string example: null nullable: true locationJson: type: string example: null nullable: true metadata: type: string example: null nullable: true isCurrent: type: boolean example: false activeFrom: type: string example: '2026-01-14T20:08:43+00:00' activeTo: type: string example: '2026-03-10T09:42:17+00:00' createdAt: type: string example: '2026-01-14T20:08:43+00:00' updatedAt: type: string example: '2026-03-10T09:42:17+00:00' collector: type: object properties: uuid: type: string example: a5ed3d06-9ac9-4eaf-8ea3-c7ec9dcafe54 collectorTypeSlug: type: string example: tcu serial: type: string example: '9' name: type: string example: 'Auto-created TCU Collector 9' enabled: type: boolean example: true farmSection: type: object properties: uuid: type: string example: 9d97ca6c-31f2-45e3-a586-2656291af1eb name: type: string example: Section1 description: type: string example: '' enabled: type: boolean example: true orderColumn: type: integer example: 0 location: type: object properties: lat: type: number example: -25.860111769169364 lng: type: number example: 28.194855451583862 locationJson: type: object properties: latitude: type: number example: -25.860111769169364 longitude: type: number example: 28.194855451583862 metadata: type: string example: null nullable: true createdAt: type: string example: '2025-12-17T18:48:47+00:00' updatedAt: type: string example: '2026-02-08T10:22:07+00:00' isUnassigned: type: boolean example: false tags: - Endpoints parameters: - in: path name: farm_uuid description: '' example: c9b4c54e-a135-4a7f-86c9-7f03b9329a1b required: true schema: type: string - in: path name: farm description: 'The UUID of the farm' example: minima required: true schema: type: string '/api/v1/sa/farms/{farm_uuid}/trackers/stats': get: summary: 'Get tracker statistics for a farm' operationId: getTrackerStatisticsForAFarm description: '' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: totalCurrent: 150 totalHistoric: 45 placed: 120 unplaced: 30 sectioned: 100 unsectioned: 50 placementPercentage: 80.0 properties: totalCurrent: type: integer example: 150 totalHistoric: type: integer example: 45 placed: type: integer example: 120 unplaced: type: integer example: 30 sectioned: type: integer example: 100 unsectioned: type: integer example: 50 placementPercentage: type: number example: 80.0 tags: - Endpoints parameters: - in: path name: farm_uuid description: '' example: c9b4c54e-a135-4a7f-86c9-7f03b9329a1b required: true schema: type: string - in: path name: farm description: 'The UUID of the farm' example: doloremque required: true schema: type: string '/api/v1/sa/farms/{farm_uuid}/trackers/section-stats': get: summary: 'Get section statistics for a farm' operationId: getSectionStatisticsForAFarm description: '' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: sections: - uuid: 550e8400-e29b-41d4-a716-446655440001 name: 'North Field' slug: north-field enabled: true orderColumn: 1 trackerCount: 50 placedCount: 45 unplacedCount: 5 properties: sections: type: array example: - uuid: 550e8400-e29b-41d4-a716-446655440001 name: 'North Field' slug: north-field enabled: true orderColumn: 1 trackerCount: 50 placedCount: 45 unplacedCount: 5 items: type: object properties: uuid: type: string example: 550e8400-e29b-41d4-a716-446655440001 name: type: string example: 'North Field' slug: type: string example: north-field enabled: type: boolean example: true orderColumn: type: integer example: 1 trackerCount: type: integer example: 50 placedCount: type: integer example: 45 unplacedCount: type: integer example: 5 tags: - Endpoints parameters: - in: path name: farm_uuid description: '' example: c9b4c54e-a135-4a7f-86c9-7f03b9329a1b required: true schema: type: string - in: path name: farm description: 'The UUID of the farm' example: autem required: true schema: type: string '/api/v1/sa/farms/{farm_uuid}/trackers/bulk-update': post: summary: 'Bulk update trackers' operationId: bulkUpdateTrackers description: '' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: success: true message: 'Updated 10 trackers' count: 10 properties: success: type: boolean example: true message: type: string example: 'Updated 10 trackers' count: type: integer example: 10 tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: tracker_uuids: type: array description: 'List of tracker UUIDs.' example: - 550e8400-e29b-41d4-a716-446655440001 items: type: string row: type: integer description: 'Row position.' example: 5 nullable: true column: type: integer description: 'Column position.' example: 10 nullable: true width_m: type: numeric description: 'Width in meters.' example: '6.0' nullable: true height_m: type: numeric description: 'Height in meters.' example: '2.5' nullable: true angle_deg: type: numeric description: 'Angle in degrees.' example: '15.0' nullable: true farm_section_uuid: type: string description: 'Farm section UUID.' example: 550e8400-e29b-41d4-a716-446655440002 nullable: true required: - tracker_uuids parameters: - in: path name: farm_uuid description: '' example: c9b4c54e-a135-4a7f-86c9-7f03b9329a1b required: true schema: type: string - in: path name: farm description: 'The UUID of the farm' example: est required: true schema: type: string '/api/v1/sa/farms/{farm_uuid}/trackers/auto-place': post: summary: 'Auto-place trackers in a grid' operationId: autoPlaceTrackersInAGrid description: '' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: success: true message: 'Trackers placed successfully' applied: true count: 25 placements: - uuid: 550e8400-e29b-41d4-a716-446655440002 collectorUuid: 550e8400-e29b-41d4-a716-446655440003 row: 1 column: 1 angleDeg: 0.0 section: uuid: 550e8400-e29b-41d4-a716-446655440001 name: 'North Field' slug: north-field properties: success: type: boolean example: true message: type: string example: 'Trackers placed successfully' applied: type: boolean example: true count: type: integer example: 25 placements: type: array example: - uuid: 550e8400-e29b-41d4-a716-446655440002 collectorUuid: 550e8400-e29b-41d4-a716-446655440003 row: 1 column: 1 angleDeg: 0 items: type: object properties: uuid: type: string example: 550e8400-e29b-41d4-a716-446655440002 collectorUuid: type: string example: 550e8400-e29b-41d4-a716-446655440003 row: type: integer example: 1 column: type: integer example: 1 angleDeg: type: number example: 0.0 section: type: object properties: uuid: type: string example: 550e8400-e29b-41d4-a716-446655440001 name: type: string example: 'North Field' slug: type: string example: north-field tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: section_uuid: type: string description: 'Section UUID for placement.' example: 550e8400-e29b-41d4-a716-446655440001 tracker_uuids: type: array description: 'Tracker UUIDs to place.' example: - 550e8400-e29b-41d4-a716-446655440002 items: type: string start_row: type: integer description: 'Starting row (1-based).' example: 1 start_column: type: integer description: 'Starting column (1-based).' example: 1 gap_width_m: type: numeric description: 'Gap width in meters.' example: '1.0' gap_height_m: type: numeric description: 'Gap height in meters.' example: '1.0' columns_per_row: type: integer description: 'Columns per row.' example: 10 angle_deg: type: numeric description: 'Optional angle override.' example: '0.0' nullable: true apply: type: boolean description: 'Whether to apply changes.' example: true required: - section_uuid - tracker_uuids parameters: - in: path name: farm_uuid description: '' example: c9b4c54e-a135-4a7f-86c9-7f03b9329a1b required: true schema: type: string - in: path name: farm description: 'The UUID of the farm' example: fugiat required: true schema: type: string '/api/v1/sa/farms/{farm_uuid}/trackers/auto-place-unplaced': post: summary: 'Auto-place unplaced trackers' operationId: autoPlaceUnplacedTrackers description: '' parameters: [] responses: 200: description: '' content: text/plain: schema: type: string example: "{\n \"success\": true,\n \"message\": \"Unplaced trackers filled successfully\",\n \"applied\": true,\n \"count\": 15,\n \"placements\": [...]\n}" tags: - Endpoints requestBody: required: false content: application/json: schema: type: object properties: section_uuid: type: string description: 'Optional section UUID filter.' example: 550e8400-e29b-41d4-a716-446655440001 nullable: true start_row: type: integer description: 'Starting row (1-based).' example: 1 start_column: type: integer description: 'Starting column (1-based).' example: 1 columns_per_row: type: integer description: 'Columns per row.' example: 10 apply: type: boolean description: 'Whether to apply changes.' example: true parameters: - in: path name: farm_uuid description: '' example: c9b4c54e-a135-4a7f-86c9-7f03b9329a1b required: true schema: type: string - in: path name: farm description: 'The UUID of the farm' example: et required: true schema: type: string '/api/v1/sa/farms/{farm_uuid}/trackers/validate-layout': get: summary: 'Validate layout for conflicts' operationId: validateLayoutForConflicts description: '' parameters: - in: query name: sectionUuid description: 'Optional section UUID filter.' example: 550e8400-e29b-41d4-a716-446655440001 required: false schema: type: string description: 'Optional section UUID filter.' example: 550e8400-e29b-41d4-a716-446655440001 responses: 200: description: '' content: application/json: schema: type: object example: valid: false totalTrackers: 150 conflicts: 2 duplicates: - row: 5 column: 10 farmSectionUuid: 550e8400-e29b-41d4-a716-446655440001 trackerUuids: - uuid1 - uuid2 properties: valid: type: boolean example: false totalTrackers: type: integer example: 150 conflicts: type: integer example: 2 duplicates: type: array example: - row: 5 column: 10 farmSectionUuid: 550e8400-e29b-41d4-a716-446655440001 trackerUuids: - uuid1 - uuid2 items: type: object properties: row: type: integer example: 5 column: type: integer example: 10 farmSectionUuid: type: string example: 550e8400-e29b-41d4-a716-446655440001 trackerUuids: type: array example: - uuid1 - uuid2 items: type: string tags: - Endpoints parameters: - in: path name: farm_uuid description: '' example: c9b4c54e-a135-4a7f-86c9-7f03b9329a1b required: true schema: type: string - in: path name: farm description: 'The UUID of the farm' example: aut required: true schema: type: string '/api/v1/sa/farms/{farm_uuid}/trackers/resolve-overlaps': post: summary: 'Resolve overlapping trackers' operationId: resolveOverlappingTrackers description: '' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: success: true message: 'Resolved 2 overlapping tracker(s)' data: applied: true resolvedCount: 2 remainingConflictCount: 0 placements: - trackerUuid: 550e8400-e29b-41d4-a716-446655440001 collectorUuid: 550e8400-e29b-41d4-a716-446655440002 previousRow: 1 previousColumn: 1 newRow: 1 newColumn: 2 properties: success: type: boolean example: true message: type: string example: 'Resolved 2 overlapping tracker(s)' data: type: object properties: applied: type: boolean example: true resolvedCount: type: integer example: 2 remainingConflictCount: type: integer example: 0 placements: type: array example: - trackerUuid: 550e8400-e29b-41d4-a716-446655440001 collectorUuid: 550e8400-e29b-41d4-a716-446655440002 previousRow: 1 previousColumn: 1 newRow: 1 newColumn: 2 items: type: object properties: trackerUuid: type: string example: 550e8400-e29b-41d4-a716-446655440001 collectorUuid: type: string example: 550e8400-e29b-41d4-a716-446655440002 previousRow: type: integer example: 1 previousColumn: type: integer example: 1 newRow: type: integer example: 1 newColumn: type: integer example: 2 tags: - Endpoints requestBody: required: false content: application/json: schema: type: object properties: sectionUuid: type: string description: 'Optional section UUID filter.' example: 550e8400-e29b-41d4-a716-446655440001 nullable: true apply: type: boolean description: 'Whether to apply changes or preview.' example: true parameters: - in: path name: farm_uuid description: '' example: c9b4c54e-a135-4a7f-86c9-7f03b9329a1b required: true schema: type: string - in: path name: farm description: 'The UUID of the farm' example: voluptatem required: true schema: type: string '/api/v1/sa/farms/{farm_uuid}/trackers/snap-to-section': post: summary: 'Snap trackers to a section' operationId: snapTrackersToASection description: '' parameters: [] responses: 200: description: '' content: text/plain: schema: type: string example: "{\n \"success\": true,\n \"message\": \"Snapped 5 tracker(s) to section North Field\",\n \"data\": {\n \"applied\": true,\n \"count\": 5,\n \"sectionUuid\": \"550e8400-e29b-41d4-a716-446655440001\",\n \"sectionName\": \"North Field\",\n \"placements\": [...]\n }\n}" tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: sectionUuid: type: string description: 'Section UUID to snap to.' example: 550e8400-e29b-41d4-a716-446655440001 trackerUuids: type: array description: 'Optional specific tracker UUIDs.' example: - 550e8400-e29b-41d4-a716-446655440002 items: type: string startRow: type: integer description: 'Starting row (1-based).' example: 1 startColumn: type: integer description: 'Starting column (1-based).' example: 1 columnsPerRow: type: integer description: 'Columns per row.' example: 10 apply: type: boolean description: 'Whether to apply changes or preview.' example: true required: - sectionUuid parameters: - in: path name: farm_uuid description: '' example: c9b4c54e-a135-4a7f-86c9-7f03b9329a1b required: true schema: type: string - in: path name: farm description: 'The UUID of the farm' example: unde required: true schema: type: string /api/v1/sa/trackers: get: summary: 'List trackers across farms (optionally filtered by farm UUID)' operationId: listTrackersAcrossFarmsoptionallyFilteredByFarmUUID description: '' parameters: - in: query name: farmUuid description: 'Optional farm UUID filter.' example: 550e8400-e29b-41d4-a716-446655440000 required: false schema: type: string description: 'Optional farm UUID filter.' example: 550e8400-e29b-41d4-a716-446655440000 - in: query name: sectionUuid description: 'Filter by section UUID.' example: 550e8400-e29b-41d4-a716-446655440001 required: false schema: type: string description: 'Filter by section UUID.' example: 550e8400-e29b-41d4-a716-446655440001 - in: query name: isCurrent description: 'Filter by current status.' example: true required: false schema: type: boolean description: 'Filter by current status.' example: true - in: query name: placed description: 'Filter by placement status.' example: true required: false schema: type: boolean description: 'Filter by placement status.' example: true - in: query name: sectioned description: 'Filter by section assignment.' example: true required: false schema: type: boolean description: 'Filter by section assignment.' example: true - in: query name: perPage description: 'Results per page (max 200).' example: 50 required: false schema: type: integer description: 'Results per page (max 200).' example: 50 responses: 200: description: '' content: application/json: schema: type: object example: data: - uuid: a205ee53-a5ce-4ecf-8103-d1ace6488432 collectorUuid: a5ed3d06-9ac9-4eaf-8ea3-c7ec9dcafe54 collectorType: TCU farmUuid: null farmSectionUuid: 9d97ca6c-31f2-45e3-a586-2656291af1eb row: 0 column: 0 widthM: '5.00' heightM: '2.00' angleDeg: '0.00' location: null locationJson: null metadata: null isCurrent: false activeFrom: '2026-01-14T20:08:43+00:00' activeTo: '2026-03-10T09:42:17+00:00' createdAt: '2026-01-14T20:08:43+00:00' updatedAt: '2026-03-10T09:42:17+00:00' collector: uuid: a5ed3d06-9ac9-4eaf-8ea3-c7ec9dcafe54 collectorTypeSlug: tcu serial: '9' name: 'Auto-created TCU Collector 9' enabled: true farmSection: uuid: 9d97ca6c-31f2-45e3-a586-2656291af1eb name: Section1 description: '' enabled: true orderColumn: 0 location: lat: -25.860111769169364 lng: 28.194855451583862 locationJson: latitude: -25.860111769169364 longitude: 28.194855451583862 metadata: null createdAt: '2025-12-17T18:48:47+00:00' updatedAt: '2026-02-08T10:22:07+00:00' isUnassigned: false - uuid: a205ee53-a5ce-4ecf-8103-d1ace6488432 collectorUuid: a5ed3d06-9ac9-4eaf-8ea3-c7ec9dcafe54 collectorType: TCU farmUuid: null farmSectionUuid: 9d97ca6c-31f2-45e3-a586-2656291af1eb row: 0 column: 0 widthM: '5.00' heightM: '2.00' angleDeg: '0.00' location: null locationJson: null metadata: null isCurrent: false activeFrom: '2026-01-14T20:08:43+00:00' activeTo: '2026-03-10T09:42:17+00:00' createdAt: '2026-01-14T20:08:43+00:00' updatedAt: '2026-03-10T09:42:17+00:00' collector: uuid: a5ed3d06-9ac9-4eaf-8ea3-c7ec9dcafe54 collectorTypeSlug: tcu serial: '9' name: 'Auto-created TCU Collector 9' enabled: true farmSection: uuid: 9d97ca6c-31f2-45e3-a586-2656291af1eb name: Section1 description: '' enabled: true orderColumn: 0 location: lat: -25.860111769169364 lng: 28.194855451583862 locationJson: latitude: -25.860111769169364 longitude: 28.194855451583862 metadata: null createdAt: '2025-12-17T18:48:47+00:00' updatedAt: '2026-02-08T10:22:07+00:00' isUnassigned: false properties: data: type: array example: - uuid: a205ee53-a5ce-4ecf-8103-d1ace6488432 collectorUuid: a5ed3d06-9ac9-4eaf-8ea3-c7ec9dcafe54 collectorType: TCU farmUuid: null farmSectionUuid: 9d97ca6c-31f2-45e3-a586-2656291af1eb row: 0 column: 0 widthM: '5.00' heightM: '2.00' angleDeg: '0.00' location: null locationJson: null metadata: null isCurrent: false activeFrom: '2026-01-14T20:08:43+00:00' activeTo: '2026-03-10T09:42:17+00:00' createdAt: '2026-01-14T20:08:43+00:00' updatedAt: '2026-03-10T09:42:17+00:00' collector: uuid: a5ed3d06-9ac9-4eaf-8ea3-c7ec9dcafe54 collectorTypeSlug: tcu serial: '9' name: 'Auto-created TCU Collector 9' enabled: true farmSection: uuid: 9d97ca6c-31f2-45e3-a586-2656291af1eb name: Section1 description: '' enabled: true orderColumn: 0 location: lat: -25.860111769169364 lng: 28.194855451583862 locationJson: latitude: -25.860111769169364 longitude: 28.194855451583862 metadata: null createdAt: '2025-12-17T18:48:47+00:00' updatedAt: '2026-02-08T10:22:07+00:00' isUnassigned: false - uuid: a205ee53-a5ce-4ecf-8103-d1ace6488432 collectorUuid: a5ed3d06-9ac9-4eaf-8ea3-c7ec9dcafe54 collectorType: TCU farmUuid: null farmSectionUuid: 9d97ca6c-31f2-45e3-a586-2656291af1eb row: 0 column: 0 widthM: '5.00' heightM: '2.00' angleDeg: '0.00' location: null locationJson: null metadata: null isCurrent: false activeFrom: '2026-01-14T20:08:43+00:00' activeTo: '2026-03-10T09:42:17+00:00' createdAt: '2026-01-14T20:08:43+00:00' updatedAt: '2026-03-10T09:42:17+00:00' collector: uuid: a5ed3d06-9ac9-4eaf-8ea3-c7ec9dcafe54 collectorTypeSlug: tcu serial: '9' name: 'Auto-created TCU Collector 9' enabled: true farmSection: uuid: 9d97ca6c-31f2-45e3-a586-2656291af1eb name: Section1 description: '' enabled: true orderColumn: 0 location: lat: -25.860111769169364 lng: 28.194855451583862 locationJson: latitude: -25.860111769169364 longitude: 28.194855451583862 metadata: null createdAt: '2025-12-17T18:48:47+00:00' updatedAt: '2026-02-08T10:22:07+00:00' isUnassigned: false items: type: object properties: uuid: type: string example: a205ee53-a5ce-4ecf-8103-d1ace6488432 collectorUuid: type: string example: a5ed3d06-9ac9-4eaf-8ea3-c7ec9dcafe54 collectorType: type: string example: TCU farmUuid: type: string example: null nullable: true farmSectionUuid: type: string example: 9d97ca6c-31f2-45e3-a586-2656291af1eb row: type: integer example: 0 column: type: integer example: 0 widthM: type: string example: '5.00' heightM: type: string example: '2.00' angleDeg: type: string example: '0.00' location: type: string example: null nullable: true locationJson: type: string example: null nullable: true metadata: type: string example: null nullable: true isCurrent: type: boolean example: false activeFrom: type: string example: '2026-01-14T20:08:43+00:00' activeTo: type: string example: '2026-03-10T09:42:17+00:00' createdAt: type: string example: '2026-01-14T20:08:43+00:00' updatedAt: type: string example: '2026-03-10T09:42:17+00:00' collector: type: object properties: uuid: type: string example: a5ed3d06-9ac9-4eaf-8ea3-c7ec9dcafe54 collectorTypeSlug: type: string example: tcu serial: type: string example: '9' name: type: string example: 'Auto-created TCU Collector 9' enabled: type: boolean example: true farmSection: type: object properties: uuid: type: string example: 9d97ca6c-31f2-45e3-a586-2656291af1eb name: type: string example: Section1 description: type: string example: '' enabled: type: boolean example: true orderColumn: type: integer example: 0 location: type: object properties: lat: type: number example: -25.860111769169364 lng: type: number example: 28.194855451583862 locationJson: type: object properties: latitude: type: number example: -25.860111769169364 longitude: type: number example: 28.194855451583862 metadata: type: string example: null nullable: true createdAt: type: string example: '2025-12-17T18:48:47+00:00' updatedAt: type: string example: '2026-02-08T10:22:07+00:00' isUnassigned: type: boolean example: false tags: - Endpoints requestBody: required: false content: application/json: schema: type: object properties: farmUuid: type: string description: 'Must be a valid UUID. The uuid of an existing record in the farms table.' example: dddabba7-d68f-37b0-9e5d-da2b9df848c6 '/api/v1/sa/trackers/{uuid}': patch: summary: 'Update a single tracker' operationId: updateASingleTracker description: '' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: success: true message: 'Tracker updated successfully' data: trackerUuid: 550e8400-e29b-41d4-a716-446655440001 layout: uuid: 550e8400-e29b-41d4-a716-446655440001 row: 5 column: 10 widthM: 6.0 heightM: 2.5 angleDeg: 15.0 farmSectionUuid: 550e8400-e29b-41d4-a716-446655440002 properties: success: type: boolean example: true message: type: string example: 'Tracker updated successfully' data: type: object properties: trackerUuid: type: string example: 550e8400-e29b-41d4-a716-446655440001 layout: type: object properties: uuid: type: string example: 550e8400-e29b-41d4-a716-446655440001 row: type: integer example: 5 column: type: integer example: 10 widthM: type: number example: 6.0 heightM: type: number example: 2.5 angleDeg: type: number example: 15.0 farmSectionUuid: type: string example: 550e8400-e29b-41d4-a716-446655440002 tags: - Endpoints requestBody: required: false content: application/json: schema: type: object properties: row: type: integer description: 'Row position.' example: 5 column: type: integer description: 'Column position.' example: 10 widthM: type: numeric description: 'Width in meters.' example: '6.0' heightM: type: numeric description: 'Height in meters.' example: '2.5' angleDeg: type: numeric description: 'Angle in degrees.' example: '15.0' farmSectionUuid: type: string description: 'Farm section UUID.' example: 550e8400-e29b-41d4-a716-446655440002 nullable: true delete: summary: 'Delete (end) a single tracker' operationId: deleteendASingleTracker description: '' parameters: [] responses: 204: description: Success content: application/json: schema: type: object example: { } properties: { } 404: description: 'Not Found' content: application/json: schema: type: object example: success: false message: 'Tracker not found' properties: success: type: boolean example: false message: type: string example: 'Tracker not found' tags: - Endpoints parameters: - in: path name: uuid description: '' example: a205ee53-a5ce-4ecf-8103-d1ace6488432 required: true schema: type: string - in: path name: tracker description: 'The UUID of the tracker' example: distinctio required: true schema: type: string /api/v1/sa/trackers/copy-locations: post: summary: 'Copy collector locations to trackers' operationId: copyCollectorLocationsToTrackers description: '' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: success: true message: 'Copied locations for 10 trackers' count: 10 properties: success: type: boolean example: true message: type: string example: 'Copied locations for 10 trackers' count: type: integer example: 10 tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: tracker_uuids: type: array description: 'Tracker UUIDs.' example: - 550e8400-e29b-41d4-a716-446655440001 items: type: string required: - tracker_uuids /api/v1/sa/data-unit-types: get: summary: '' operationId: getApiV1SaDataUnitTypes description: '' parameters: - in: query name: enabled description: 'Filter by enabled status.' example: true required: false schema: type: boolean description: 'Filter by enabled status.' example: true - in: query name: search description: 'Search by name, slug, or description. Must not be greater than 255 characters.' example: celsius required: false schema: type: string description: 'Search by name, slug, or description. Must not be greater than 255 characters.' example: celsius - in: query name: dataTypeSlug description: 'Filter by data type slug. The slug of an existing record in the data_types table.' example: numeric required: false schema: type: string description: 'Filter by data type slug. The slug of an existing record in the data_types table.' example: numeric - in: query name: orderBy description: 'Sort field.' example: orderColumn required: false schema: type: string description: 'Sort field.' example: orderColumn enum: - orderColumn - name - slug - createdAt - updatedAt - in: query name: direction description: 'Sort direction.' example: asc required: false schema: type: string description: 'Sort direction.' example: asc enum: - asc - desc - in: query name: perPage description: 'Items per page (max 200). Must be at least 1. Must not be greater than 200.' example: 50 required: false schema: type: integer description: 'Items per page (max 200). Must be at least 1. Must not be greater than 200.' example: 50 responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints post: summary: '' operationId: postApiV1SaDataUnitTypes description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: data_type_slug: type: string description: '' example: null order_column: type: string description: '' example: null slug: type: string description: 'Unique identifier for the data unit. Must not be greater than 255 characters.' example: celsius name: type: string description: 'Display name for the data unit. Must not be greater than 255 characters.' example: Celsius unit: type: string description: 'Unit symbol or abbreviation. Must not be greater than 50 characters.' example: Β°C nullable: true description: type: string description: 'Description of the data unit.' example: 'Temperature in degrees Celsius' nullable: true dataTypeSlug: type: string description: 'Data type identifier (slug). The slug of an existing record in the data_types table.' example: numeric orderColumn: type: integer description: 'Display order.' example: 1 enabled: type: boolean description: 'Whether the data unit is enabled.' example: true required: - slug - name - dataTypeSlug /api/v1/sa/data-unit-types/export: get: summary: '' operationId: getApiV1SaDataUnitTypesExport description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints '/api/v1/sa/data-unit-types/{dataUnit_slug}': get: summary: '' operationId: getApiV1SaDataUnitTypesDataUnit_slug description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints patch: summary: '' operationId: patchApiV1SaDataUnitTypesDataUnit_slug description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: data_type_slug: type: string description: '' example: null order_column: type: string description: '' example: null slug: type: string description: 'Unique identifier for the data unit. Must not be greater than 255 characters.' example: celsius-updated name: type: string description: 'Display name for the data unit. Must not be greater than 255 characters.' example: 'Celsius Updated' unit: type: string description: 'Unit symbol or abbreviation. Must not be greater than 50 characters.' example: Β°C nullable: true description: type: string description: 'Description of the data unit.' example: 'Updated temperature description' nullable: true dataTypeSlug: type: string description: 'Data type identifier (slug). The slug of an existing record in the data_types table.' example: numeric orderColumn: type: integer description: 'Display order.' example: 1 enabled: type: boolean description: 'Whether the data unit is enabled.' example: true required: - slug - name - dataTypeSlug delete: summary: '' operationId: deleteApiV1SaDataUnitTypesDataUnit_slug description: '' parameters: [] responses: { } tags: - Endpoints parameters: - in: path name: dataUnit_slug description: 'The slug of the dataUnit.' example: unknown required: true schema: type: string /api/v1/sa/collector-measurement-types: get: summary: '' operationId: getApiV1SaCollectorMeasurementTypes description: '' parameters: - in: query name: enabled description: 'Filter by enabled status.' example: true required: false schema: type: boolean description: 'Filter by enabled status.' example: true - in: query name: orderBy description: 'Sort field.' example: orderColumn required: false schema: type: string description: 'Sort field.' example: orderColumn enum: - orderColumn - name - slug - createdAt - updatedAt - in: query name: direction description: 'Sort direction.' example: asc required: false schema: type: string description: 'Sort direction.' example: asc enum: - asc - desc - in: query name: perPage description: 'Items per page (max 200). Must be at least 1. Must not be greater than 200.' example: 50 required: false schema: type: integer description: 'Items per page (max 200). Must be at least 1. Must not be greater than 200.' example: 50 responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints post: summary: '' operationId: postApiV1SaCollectorMeasurementTypes description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: slug: type: string description: 'Unique identifier for the measurement type. Must not be greater than 255 characters.' example: temperature name: type: string description: 'Display name for the measurement type. Must not be greater than 255 characters.' example: Temperature description: type: string description: 'Description of the measurement type.' example: 'Ambient temperature measurement' nullable: true dataUnitSlug: type: string description: 'Data unit identifier (slug). The slug of an existing record in the data_units table.' example: celsius collectorTypeSlug: type: string description: 'Collector type this measurement applies to (ncu, tcu, or null for both). The slug of an existing record in the collector_types table.' example: tcu nullable: true orderColumn: type: integer description: 'Display order.' example: 1 enabled: type: boolean description: 'Whether the measurement type is enabled.' example: true required: - slug - name - dataUnitSlug /api/v1/sa/collector-measurement-types/export: get: summary: '' operationId: getApiV1SaCollectorMeasurementTypesExport description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints '/api/v1/sa/collector-measurement-types/{collectorMeasurementType_slug}': get: summary: '' operationId: getApiV1SaCollectorMeasurementTypesCollectorMeasurementType_slug description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints patch: summary: '' operationId: patchApiV1SaCollectorMeasurementTypesCollectorMeasurementType_slug description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: slug: type: string description: 'Unique identifier for the measurement type. Must not be greater than 255 characters.' example: temperature-updated name: type: string description: 'Display name for the measurement type. Must not be greater than 255 characters.' example: 'Temperature Updated' description: type: string description: 'Description of the measurement type.' example: 'Updated ambient temperature measurement' nullable: true dataUnitSlug: type: string description: 'Data unit identifier (slug). The slug of an existing record in the data_units table.' example: celsius collectorTypeSlug: type: string description: 'Collector type this measurement applies to (ncu, tcu, or null for both). The slug of an existing record in the collector_types table.' example: tcu nullable: true orderColumn: type: integer description: 'Display order.' example: 1 enabled: type: boolean description: 'Whether the measurement type is enabled.' example: true required: - slug - name - dataUnitSlug delete: summary: '' operationId: deleteApiV1SaCollectorMeasurementTypesCollectorMeasurementType_slug description: '' parameters: [] responses: { } tags: - Endpoints parameters: - in: path name: collectorMeasurementType_slug description: 'The slug of the collectorMeasurementType.' example: unknown required: true schema: type: string /api/v1/sa/collector-parameter-types: get: summary: '' operationId: getApiV1SaCollectorParameterTypes description: '' parameters: - in: query name: enabled description: 'Filter by enabled status.' example: true required: false schema: type: boolean description: 'Filter by enabled status.' example: true - in: query name: orderBy description: 'Sort field.' example: orderColumn required: false schema: type: string description: 'Sort field.' example: orderColumn enum: - orderColumn - name - slug - createdAt - updatedAt - in: query name: direction description: 'Sort direction.' example: asc required: false schema: type: string description: 'Sort direction.' example: asc enum: - asc - desc - in: query name: perPage description: 'Items per page (max 200). Must be at least 1. Must not be greater than 200.' example: 50 required: false schema: type: integer description: 'Items per page (max 200). Must be at least 1. Must not be greater than 200.' example: 50 responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints post: summary: '' operationId: postApiV1SaCollectorParameterTypes description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: slug: type: string description: 'Unique identifier for the parameter type. Must not be greater than 255 characters.' example: tracking-mode name: type: string description: 'Display name for the parameter type. Must not be greater than 255 characters.' example: 'Tracking Mode' description: type: string description: 'Description of the parameter type.' example: 'Collector tracking mode configuration' nullable: true dataUnitSlug: type: string description: 'Data unit identifier (slug). The slug of an existing record in the data_units table.' example: string collectorTypeSlug: type: string description: 'Collector type this parameter applies to (ncu, tcu, or null for both). The slug of an existing record in the collector_types table.' example: tcu nullable: true orderColumn: type: integer description: 'Display order.' example: 1 enabled: type: boolean description: 'Whether the parameter type is enabled.' example: true isReadOnly: type: boolean description: 'Whether the parameter is read-only.' example: false required: - slug - name - dataUnitSlug /api/v1/sa/collector-parameter-types/export: get: summary: '' operationId: getApiV1SaCollectorParameterTypesExport description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints '/api/v1/sa/collector-parameter-types/{collectorParameterType_slug}': get: summary: '' operationId: getApiV1SaCollectorParameterTypesCollectorParameterType_slug description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints patch: summary: '' operationId: patchApiV1SaCollectorParameterTypesCollectorParameterType_slug description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: slug: type: string description: 'Unique identifier for the parameter type. Must not be greater than 255 characters.' example: tracking-mode-updated name: type: string description: 'Display name for the parameter type. Must not be greater than 255 characters.' example: 'Tracking Mode Updated' description: type: string description: 'Description of the parameter type.' example: 'Updated collector tracking mode configuration' nullable: true dataUnitSlug: type: string description: 'Data unit identifier (slug). The slug of an existing record in the data_units table.' example: string collectorTypeSlug: type: string description: 'Collector type this parameter applies to (ncu, tcu, or null for both). The slug of an existing record in the collector_types table.' example: tcu nullable: true orderColumn: type: integer description: 'Display order.' example: 1 enabled: type: boolean description: 'Whether the parameter type is enabled.' example: true isReadOnly: type: boolean description: 'Whether the parameter is read-only.' example: false required: - slug - name - dataUnitSlug delete: summary: '' operationId: deleteApiV1SaCollectorParameterTypesCollectorParameterType_slug description: '' parameters: [] responses: { } tags: - Endpoints parameters: - in: path name: collectorParameterType_slug description: 'The slug of the collectorParameterType.' example: unknown required: true schema: type: string /api/v1/sa/collector-parameter-validation-rules: get: summary: '' operationId: getApiV1SaCollectorParameterValidationRules description: '' parameters: - in: query name: enabled description: 'Filter by enabled status.' example: true required: false schema: type: boolean description: 'Filter by enabled status.' example: true - in: query name: orderBy description: 'Sort field.' example: collectorParameterTypeSlug required: false schema: type: string description: 'Sort field.' example: collectorParameterTypeSlug enum: - collectorParameterTypeSlug - createdAt - updatedAt - in: query name: direction description: 'Sort direction.' example: asc required: false schema: type: string description: 'Sort direction.' example: asc enum: - asc - desc - in: query name: perPage description: 'Items per page (max 200). Must be at least 1. Must not be greater than 200.' example: 50 required: false schema: type: integer description: 'Items per page (max 200). Must be at least 1. Must not be greater than 200.' example: 50 responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints post: summary: '' operationId: postApiV1SaCollectorParameterValidationRules description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: collectorParameterTypeSlug: type: string description: 'Parameter type identifier. The slug of an existing record in the collector_parameter_types table.' example: tracking-mode minValueDecimal: type: number description: 'Minimum numeric value.' example: 0.0 nullable: true maxValueDecimal: type: number description: 'Maximum numeric value.' example: 100.0 nullable: true stringRegex: type: string description: 'Regex pattern for string validation. Must not be greater than 512 characters.' example: '^[a-zA-Z]+$' nullable: true defaultValue: type: string description: 'Default value for the parameter.' example: auto nullable: true enabled: type: boolean description: 'Whether the validation rule is enabled.' example: true required: - collectorParameterTypeSlug '/api/v1/sa/collector-parameter-validation-rules/{collectorParameterType_slug}': get: summary: '' operationId: getApiV1SaCollectorParameterValidationRulesCollectorParameterType_slug description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints patch: summary: '' operationId: patchApiV1SaCollectorParameterValidationRulesCollectorParameterType_slug description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: false content: application/json: schema: type: object properties: collectorParameterTypeSlug: type: string description: 'Parameter type identifier. The slug of an existing record in the collector_parameter_types table.' example: tracking-mode minValueDecimal: type: number description: 'Minimum numeric value.' example: 0.0 nullable: true maxValueDecimal: type: number description: 'Maximum numeric value.' example: 100.0 nullable: true stringRegex: type: string description: 'Regex pattern for string validation. Must not be greater than 512 characters.' example: '^[a-zA-Z]+$' nullable: true defaultValue: type: string description: 'Default value for the parameter.' example: manual nullable: true enabled: type: boolean description: 'Whether the validation rule is enabled.' example: true delete: summary: '' operationId: deleteApiV1SaCollectorParameterValidationRulesCollectorParameterType_slug description: '' parameters: [] responses: { } tags: - Endpoints parameters: - in: path name: collectorParameterType_slug description: 'The slug of the collectorParameterType.' example: unknown required: true schema: type: string /api/v1/sa/collector-parameter-validation-rules/validate: post: summary: '' operationId: postApiV1SaCollectorParameterValidationRulesValidate description: '' parameters: [] responses: { } tags: - Endpoints /api/v1/sa/device-model-types: get: summary: '' operationId: getApiV1SaDeviceModelTypes description: '' parameters: - in: query name: enabled description: 'Filter by enabled status.' example: true required: false schema: type: boolean description: 'Filter by enabled status.' example: true - in: query name: collectorTypeSlug description: 'Filter by collector type slug. The slug of an existing record in the collector_types table.' example: ncu required: false schema: type: string description: 'Filter by collector type slug. The slug of an existing record in the collector_types table.' example: ncu - in: query name: orderBy description: 'Sort field.' example: orderColumn required: false schema: type: string description: 'Sort field.' example: orderColumn enum: - orderColumn - name - slug - createdAt - updatedAt - in: query name: direction description: 'Sort direction.' example: asc required: false schema: type: string description: 'Sort direction.' example: asc enum: - asc - desc - in: query name: perPage description: 'Items per page (max 200). Must be at least 1. Must not be greater than 200.' example: 50 required: false schema: type: integer description: 'Items per page (max 200). Must be at least 1. Must not be greater than 200.' example: 50 responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints post: summary: '' operationId: postApiV1SaDeviceModelTypes description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: slug: type: string description: 'Unique identifier for the device model type (auto-generated from name if omitted). Must not be greater than 255 characters.' example: ncu-v3 name: type: string description: 'Display name for the device model type. Must not be greater than 255 characters.' example: 'NCU Version 3' description: type: string description: 'Description of the device model type.' example: 'Network Control Unit version 3 with advanced features' nullable: true manufacturerTypeSlug: type: string description: 'Manufacturer type slug. The slug of an existing record in the manufacturer_types table.' example: tracklab nullable: true collectorTypeSlug: type: string description: 'Associated collector type identifier (slug). The slug of an existing record in the collector_types table.' example: ncu nullable: true hardwareVersionSlugs: type: array description: '' example: null items: type: object properties: slug: type: string description: 'This field is required when hardwareVersionSlugs.* is present. The slug of an existing record in the hardware_version_types table.' example: fugit isPrimary: type: boolean description: '' example: false notes: type: string description: '' example: excepturi capabilities: type: object description: 'Device capabilities as slug => value pairs.' example: wifi: 'true' channels: '8' properties: { } nullable: true orderColumn: type: integer description: 'Display order.' example: 1 enabled: type: boolean description: 'Whether the device model type is enabled.' example: true required: - name /api/v1/sa/device-model-types/export: get: summary: '' operationId: getApiV1SaDeviceModelTypesExport description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints '/api/v1/sa/device-model-types/{deviceModelType_slug}': get: summary: '' operationId: getApiV1SaDeviceModelTypesDeviceModelType_slug description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints patch: summary: '' operationId: patchApiV1SaDeviceModelTypesDeviceModelType_slug description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: false content: application/json: schema: type: object properties: slug: type: string description: 'Unique identifier for the device model type. Must not be greater than 255 characters.' example: ncu-v3-updated name: type: string description: 'Display name for the device model type. Must not be greater than 255 characters.' example: 'NCU Version 3 Updated' description: type: string description: 'Description of the device model type.' example: 'Updated Network Control Unit version 3' nullable: true manufacturerTypeSlug: type: string description: 'Manufacturer type slug. The slug of an existing record in the manufacturer_types table.' example: tracklab nullable: true collectorTypeSlug: type: string description: 'Associated collector type identifier (slug). The slug of an existing record in the collector_types table.' example: ncu nullable: true hardwareVersionSlugs: type: array description: '' example: null items: type: object properties: slug: type: string description: 'This field is required when hardwareVersionSlugs.* is present. The slug of an existing record in the hardware_version_types table.' example: sit isPrimary: type: boolean description: '' example: false notes: type: string description: '' example: quaerat capabilities: type: object description: 'Device capabilities as slug => value pairs.' example: wifi: 'true' channels: '8' properties: { } nullable: true orderColumn: type: integer description: 'Display order.' example: 1 enabled: type: boolean description: 'Whether the device model type is enabled.' example: true delete: summary: '' operationId: deleteApiV1SaDeviceModelTypesDeviceModelType_slug description: '' parameters: [] responses: { } tags: - Endpoints parameters: - in: path name: deviceModelType_slug description: 'The slug of the deviceModelType.' example: unknown required: true schema: type: string /api/v1/sa/manufacturer-types: get: summary: '' operationId: getApiV1SaManufacturerTypes description: '' parameters: - in: query name: enabled description: 'Filter by enabled status.' example: true required: false schema: type: boolean description: 'Filter by enabled status.' example: true - in: query name: search description: 'Search by name/slug. Must not be greater than 255 characters.' example: tracklab required: false schema: type: string description: 'Search by name/slug. Must not be greater than 255 characters.' example: tracklab - in: query name: orderBy description: 'Sort field.' example: orderColumn required: false schema: type: string description: 'Sort field.' example: orderColumn enum: - orderColumn - name - slug - createdAt - updatedAt - in: query name: direction description: 'Sort direction.' example: asc required: false schema: type: string description: 'Sort direction.' example: asc enum: - asc - desc - in: query name: perPage description: 'Items per page (max 200). Must be at least 1. Must not be greater than 200.' example: 50 required: false schema: type: integer description: 'Items per page (max 200). Must be at least 1. Must not be greater than 200.' example: 50 responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints post: summary: '' operationId: postApiV1SaManufacturerTypes description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: slug: type: string description: 'Unique identifier for the manufacturer. Must not be greater than 255 characters.' example: tracklab name: type: string description: 'Display name for the manufacturer. Must not be greater than 255 characters.' example: TrackLab description: type: string description: 'Description of the manufacturer.' example: 'Solar tracking systems manufacturer' nullable: true websiteUrl: type: string description: 'Manufacturer website URL. Must be a valid URL. Must not be greater than 500 characters.' example: 'https://tracklab.com' nullable: true supportEmail: type: string description: 'Support email address. Must be a valid email address. Must not be greater than 255 characters.' example: support@tracklab.com nullable: true supportUrl: type: string description: 'Support page URL. Must be a valid URL. Must not be greater than 500 characters.' example: 'https://tracklab.com/support' nullable: true orderColumn: type: integer description: 'Display order.' example: 1 enabled: type: boolean description: 'Whether the manufacturer is enabled.' example: true required: - slug - name /api/v1/sa/manufacturer-types/export: get: summary: '' operationId: getApiV1SaManufacturerTypesExport description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints '/api/v1/sa/manufacturer-types/{manufacturerType_slug}': get: summary: '' operationId: getApiV1SaManufacturerTypesManufacturerType_slug description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints patch: summary: '' operationId: patchApiV1SaManufacturerTypesManufacturerType_slug description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: false content: application/json: schema: type: object properties: slug: type: string description: 'Manufacturer type slug (unique). Must not be greater than 255 characters.' example: tracklab name: type: string description: 'Manufacturer display name (unique). Must not be greater than 255 characters.' example: TrackLab description: type: string description: 'Optional description.' example: 'TrackLab supported manufacturer' nullable: true websiteUrl: type: string description: 'Optional website URL. Must be a valid URL. Must not be greater than 500 characters.' example: 'https://tracklab.example' nullable: true supportEmail: type: string description: 'Optional support email address. Must be a valid email address. Must not be greater than 255 characters.' example: support@tracklab.example nullable: true supportUrl: type: string description: 'Optional support URL. Must be a valid URL. Must not be greater than 500 characters.' example: 'https://tracklab.example/support' nullable: true orderColumn: type: integer description: 'Optional display order.' example: 10 enabled: type: boolean description: 'Enable/disable this type.' example: true delete: summary: '' operationId: deleteApiV1SaManufacturerTypesManufacturerType_slug description: '' parameters: [] responses: { } tags: - Endpoints parameters: - in: path name: manufacturerType_slug description: 'The slug of the manufacturerType.' example: unknown required: true schema: type: string /api/v1/sa/hardware-version-types: get: summary: '' operationId: getApiV1SaHardwareVersionTypes description: '' parameters: - in: query name: enabled description: 'Filter by enabled status.' example: true required: false schema: type: boolean description: 'Filter by enabled status.' example: true - in: query name: search description: 'Search by version/slug. Must not be greater than 255 characters.' example: '1.0' required: false schema: type: string description: 'Search by version/slug. Must not be greater than 255 characters.' example: '1.0' - in: query name: orderBy description: 'Sort field.' example: orderColumn required: false schema: type: string description: 'Sort field.' example: orderColumn enum: - orderColumn - version - slug - createdAt - updatedAt - in: query name: direction description: 'Sort direction.' example: asc required: false schema: type: string description: 'Sort direction.' example: asc enum: - asc - desc - in: query name: perPage description: 'Items per page (max 200). Must be at least 1. Must not be greater than 200.' example: 50 required: false schema: type: integer description: 'Items per page (max 200). Must be at least 1. Must not be greater than 200.' example: 50 responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints post: summary: '' operationId: postApiV1SaHardwareVersionTypes description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: slug: type: string description: 'Unique identifier (auto-generated from version if not provided). Must not be greater than 255 characters.' example: v1-0-0 nullable: true version: type: string description: 'Semantic version string (e.g., 1.0, 2.5.1). Must match the regex /^\d+(\.\d+){0,2}$/. Must not be greater than 50 characters.' example: 1.0.0 description: type: string description: 'Description of the hardware version.' example: 'Initial production release' nullable: true releaseDate: type: string description: 'Release date (YYYY-MM-DD). Must be a valid date.' example: '2024-01-15' nullable: true orderColumn: type: integer description: 'Display order.' example: 1 enabled: type: boolean description: 'Whether the hardware version is enabled.' example: true required: - version /api/v1/sa/hardware-version-types/export: get: summary: '' operationId: getApiV1SaHardwareVersionTypesExport description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints '/api/v1/sa/hardware-version-types/{hardwareVersionType_slug}': get: summary: '' operationId: getApiV1SaHardwareVersionTypesHardwareVersionType_slug description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints patch: summary: '' operationId: patchApiV1SaHardwareVersionTypesHardwareVersionType_slug description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: false content: application/json: schema: type: object properties: slug: type: string description: 'Hardware version slug (unique). Must not be greater than 255 characters.' example: ncu-v2 version: type: string description: 'Semantic version number (e.g., 1.0, 1.0.0). Must match the regex /^\d+(\.\d+){0,2}$/. Must not be greater than 50 characters.' example: 2.0.0 description: type: string description: 'Optional description.' example: 'Second generation NCU hardware' nullable: true releaseDate: type: string description: 'Optional release date (YYYY-MM-DD). Must be a valid date.' example: '2025-01-01' nullable: true orderColumn: type: integer description: 'Optional display order.' example: 10 enabled: type: boolean description: 'Enable/disable this type.' example: true delete: summary: '' operationId: deleteApiV1SaHardwareVersionTypesHardwareVersionType_slug description: '' parameters: [] responses: { } tags: - Endpoints parameters: - in: path name: hardwareVersionType_slug description: 'The slug of the hardwareVersionType.' example: unknown required: true schema: type: string /api/v1/sa/capability-types: get: summary: '' operationId: getApiV1SaCapabilityTypes description: '' parameters: - in: query name: enabled description: 'Filter by enabled status.' example: true required: false schema: type: boolean description: 'Filter by enabled status.' example: true - in: query name: category description: 'Filter by capability category. Must not be greater than 100 characters.' example: power required: false schema: type: string description: 'Filter by capability category. Must not be greater than 100 characters.' example: power - in: query name: valueType description: 'Filter by value type.' example: boolean required: false schema: type: string description: 'Filter by value type.' example: boolean enum: - boolean - integer - string - array - in: query name: search description: 'Search by name/slug. Must not be greater than 255 characters.' example: tracking required: false schema: type: string description: 'Search by name/slug. Must not be greater than 255 characters.' example: tracking - in: query name: orderBy description: 'Sort field.' example: orderColumn required: false schema: type: string description: 'Sort field.' example: orderColumn enum: - orderColumn - name - slug - createdAt - updatedAt - in: query name: direction description: 'Sort direction.' example: asc required: false schema: type: string description: 'Sort direction.' example: asc enum: - asc - desc - in: query name: perPage description: 'Items per page (max 200). Must be at least 1. Must not be greater than 200.' example: 50 required: false schema: type: integer description: 'Items per page (max 200). Must be at least 1. Must not be greater than 200.' example: 50 responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints post: summary: '' operationId: postApiV1SaCapabilityTypes description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: slug: type: string description: 'Unique identifier for the capability. Must not be greater than 255 characters.' example: wifi name: type: string description: 'Display name for the capability. Must not be greater than 255 characters.' example: WiFi description: type: string description: 'Description of the capability.' example: 'WiFi connectivity support' nullable: true valueType: type: string description: 'Type of value (boolean, integer, string, array).' example: boolean enum: - boolean - integer - string - array defaultValue: type: string description: 'Default value for this capability. Must not be greater than 255 characters.' example: 'true' nullable: true category: type: string description: 'Category for grouping (e.g., communication, hardware, features). Must not be greater than 100 characters.' example: communication orderColumn: type: integer description: 'Display order.' example: 1 enabled: type: boolean description: 'Whether the capability is enabled.' example: true required: - slug - name /api/v1/sa/capability-types/export: get: summary: '' operationId: getApiV1SaCapabilityTypesExport description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints /api/v1/sa/capability-types/categories: get: summary: '' operationId: getApiV1SaCapabilityTypesCategories description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints '/api/v1/sa/capability-types/{capabilityType_slug}': get: summary: '' operationId: getApiV1SaCapabilityTypesCapabilityType_slug description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints patch: summary: '' operationId: patchApiV1SaCapabilityTypesCapabilityType_slug description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: false content: application/json: schema: type: object properties: slug: type: string description: 'Capability type slug (unique). Must not be greater than 255 characters.' example: supports-tracking name: type: string description: 'Capability display name. Must not be greater than 255 characters.' example: 'Supports tracking' description: type: string description: 'Optional description.' example: 'Whether the device supports tracking mode' nullable: true valueType: type: string description: 'Type of the stored value.' example: boolean enum: - boolean - integer - string - array defaultValue: type: string description: 'Optional default value (stored as string). Must not be greater than 255 characters.' example: 'false' nullable: true category: type: string description: 'Capability category. Must not be greater than 100 characters.' example: tracking orderColumn: type: integer description: 'Optional display order.' example: 10 enabled: type: boolean description: 'Enable/disable this type.' example: true delete: summary: '' operationId: deleteApiV1SaCapabilityTypesCapabilityType_slug description: '' parameters: [] responses: { } tags: - Endpoints parameters: - in: path name: capabilityType_slug description: 'The slug of the capabilityType.' example: unknown required: true schema: type: string '/api/v1/sa/c/{company_slug}/device-commands/{collector_uuid}/raw': post: summary: '' operationId: postApiV1SaCCompany_slugDeviceCommandsCollector_uuidRaw description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: command: type: string description: 'Command payload β€” a string for simple commands (e.g. "restart") or an object for structured commands.' example: setParameter: key: reporting_interval value: 60 ttl: type: integer description: 'Command TTL in seconds (defaults to 3600 if omitted). Must be at least 1.' example: 3600 nullable: true required: - command parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: collector_uuid description: '' example: aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa required: true schema: type: string '/api/v1/sa/c/{company_slug}/device-commands/{collector_uuid}/broadcast-parameters': post: summary: 'Broadcast Parameter Update' operationId: broadcastParameterUpdate description: "Send a single MQTT broadcast command to all child TCUs of an NCU,\nwhile storing parameters locally per-child-TCU." parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: parameters: type: object description: 'Key-value pairs of parameter slugs and their values' example: [] properties: { } required: - parameters parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: collector_uuid description: '' example: aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa required: true schema: type: string - in: path name: company description: 'The slug of the company' example: soluta required: true schema: type: string - in: path name: collector description: 'The UUID of the NCU collector' example: sed required: true schema: type: string '/api/v1/sa/c/{company_slug}/device-groups': get: summary: '' operationId: getApiV1SaCCompany_slugDeviceGroups description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints post: summary: '' operationId: postApiV1SaCCompany_slugDeviceGroups description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: name: type: string description: 'Device group name (unique per company). Must not be greater than 255 characters.' example: 'Section A Collectors' description: type: string description: 'Description of the device group.' example: 'All collectors in section A of the farm' nullable: true targetFilters: type: object description: 'Filters to auto-select collectors.' example: deviceModelTypeSlugs: - ncu-v2 - tcu-v1 farmUuids: - 550e8400-e29b-41d4-a716-446655440000 properties: deviceModelTypeSlugs: type: array description: 'The slug of an existing record in the device_model_types table.' example: - ncu-v2 - tcu-v1 items: type: string farmUuids: type: array description: 'Must be a valid UUID. The uuid of an existing record in the farms table.' example: - 550e8400-e29b-41d4-a716-446655440000 items: type: string siteUuids: type: array description: 'Must be a valid UUID. The uuid of an existing record in the sites table.' example: - f965dfca-9ad3-3aac-bca6-314a3d2ca63b items: type: string collectorUuids: type: array description: 'Must be a valid UUID. The uuid of an existing record in the collectors table.' example: - 4b75035a-4ac9-34d1-8276-e5fe3fc533d9 items: type: string excludeCollectorUuids: type: array description: 'Must be a valid UUID. The uuid of an existing record in the collectors table.' example: - 87c9c27d-3b5e-33aa-a451-c44e711fc4d2 items: type: string nullable: true collectorUuids: type: array description: 'Must be a valid UUID. The uuid of an existing record in the collectors table.' example: - ac8acc36-da1e-35a8-b807-098a620230c2 items: type: string required: - name parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string '/api/v1/sa/c/{company_slug}/device-groups/{deviceGroup_uuid}': get: summary: '' operationId: getApiV1SaCCompany_slugDeviceGroupsDeviceGroup_uuid description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints put: summary: '' operationId: putApiV1SaCCompany_slugDeviceGroupsDeviceGroup_uuid description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: false content: application/json: schema: type: object properties: name: type: string description: 'Device group name (unique per company). Must not be greater than 255 characters.' example: 'Section A Collectors Updated' description: type: string description: 'Description of the device group.' example: 'Updated collectors in section A' nullable: true targetFilters: type: object description: 'Filters to auto-select collectors.' example: deviceModelTypeSlugs: - ncu-v2 - tcu-v1 - ncu-v3 farmUuids: - 550e8400-e29b-41d4-a716-446655440000 - 550e8400-e29b-41d4-a716-446655440001 properties: deviceModelTypeSlugs: type: array description: 'The slug of an existing record in the device_model_types table.' example: - ncu-v2 - tcu-v1 - ncu-v3 items: type: string farmUuids: type: array description: 'Must be a valid UUID. The uuid of an existing record in the farms table.' example: - 550e8400-e29b-41d4-a716-446655440000 - 550e8400-e29b-41d4-a716-446655440001 items: type: string siteUuids: type: array description: 'Must be a valid UUID. The uuid of an existing record in the sites table.' example: - a4683fe9-438a-3bf7-8679-a6a24316dd06 items: type: string collectorUuids: type: array description: 'Must be a valid UUID. The uuid of an existing record in the collectors table.' example: - 6a43dd00-329f-3f22-8fe1-b2ea72d600e9 items: type: string excludeCollectorUuids: type: array description: 'Must be a valid UUID. The uuid of an existing record in the collectors table.' example: - 9224be29-9381-3756-8a3e-275cf05603a2 items: type: string nullable: true collectorUuids: type: array description: 'Must be a valid UUID. The uuid of an existing record in the collectors table.' example: - f7197dd9-4487-3018-b593-72fd11cccdb1 items: type: string patch: summary: '' operationId: patchApiV1SaCCompany_slugDeviceGroupsDeviceGroup_uuid description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: false content: application/json: schema: type: object properties: name: type: string description: 'Device group name (unique per company). Must not be greater than 255 characters.' example: 'Section A Collectors Updated' description: type: string description: 'Description of the device group.' example: 'Updated collectors in section A' nullable: true targetFilters: type: object description: 'Filters to auto-select collectors.' example: deviceModelTypeSlugs: - ncu-v2 - tcu-v1 - ncu-v3 farmUuids: - 550e8400-e29b-41d4-a716-446655440000 - 550e8400-e29b-41d4-a716-446655440001 properties: deviceModelTypeSlugs: type: array description: 'The slug of an existing record in the device_model_types table.' example: - ncu-v2 - tcu-v1 - ncu-v3 items: type: string farmUuids: type: array description: 'Must be a valid UUID. The uuid of an existing record in the farms table.' example: - 550e8400-e29b-41d4-a716-446655440000 - 550e8400-e29b-41d4-a716-446655440001 items: type: string siteUuids: type: array description: 'Must be a valid UUID. The uuid of an existing record in the sites table.' example: - 8b359f57-1303-3235-b6a7-2fde0afc1d3c items: type: string collectorUuids: type: array description: 'Must be a valid UUID. The uuid of an existing record in the collectors table.' example: - 3f5a1511-1ee5-3cdd-9bdd-e96ac8d2585f items: type: string excludeCollectorUuids: type: array description: 'Must be a valid UUID. The uuid of an existing record in the collectors table.' example: - 998df23f-29cd-3360-93d1-3d3c3113a7f9 items: type: string nullable: true collectorUuids: type: array description: 'Must be a valid UUID. The uuid of an existing record in the collectors table.' example: - 3655e560-493f-39e1-8311-ebf730a73675 items: type: string delete: summary: '' operationId: deleteApiV1SaCCompany_slugDeviceGroupsDeviceGroup_uuid description: '' parameters: [] responses: { } tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: deviceGroup_uuid description: '' example: a2f63e5f-8488-4b5f-a10e-04616e26f78d required: true schema: type: string '/api/v1/sa/c/{company_slug}/device-groups/{deviceGroup_uuid}/collectors': post: summary: '' operationId: postApiV1SaCCompany_slugDeviceGroupsDeviceGroup_uuidCollectors description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: action: type: string description: 'Action to perform: add or remove collectors.' example: add enum: - add - remove collectorUuids: type: array description: 'Must be a valid UUID. The uuid of an existing record in the collectors table.' example: - 333b9775-74a2-3052-8116-932b53b86bc7 items: type: string required: - action parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: deviceGroup_uuid description: '' example: a2f63e5f-8488-4b5f-a10e-04616e26f78d required: true schema: type: string '/api/v1/sa/c/{company_slug}/device-groups/{deviceGroup_uuid}/parameters': post: summary: '' operationId: postApiV1SaCCompany_slugDeviceGroupsDeviceGroup_uuidParameters description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: parameters: type: array description: '' example: - tempore items: type: string required: - parameters parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: deviceGroup_uuid description: '' example: a2f63e5f-8488-4b5f-a10e-04616e26f78d required: true schema: type: string /api/v1/sa/doc-lib/sections: get: summary: 'List all document library sections.' operationId: listAllDocumentLibrarySections description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints post: summary: 'Create a new document library section.' operationId: createANewDocumentLibrarySection description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: name: type: string description: 'The name of the document library section. Must not be greater than 255 characters.' example: 'Technical Manuals' description: type: string description: 'An optional description of the section. Must not be greater than 1000 characters.' example: 'Technical documentation and user manuals for all product lines.' nullable: true enabled: type: boolean description: '' example: false nullable: true required: - name '/api/v1/sa/doc-lib/sections/{uuid}': patch: summary: 'Update an existing document library section.' operationId: updateAnExistingDocumentLibrarySection description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: name: type: string description: 'The updated name of the section. Must not be greater than 255 characters.' example: 'Technical Manuals' description: type: string description: 'The updated description of the section. Must not be greater than 1000 characters.' example: 'Technical documentation and user manuals for all product lines.' nullable: true enabled: type: boolean description: '' example: true nullable: true required: - name delete: summary: 'Delete a document library section.' operationId: deleteADocumentLibrarySection description: '' parameters: [] responses: { } tags: - Endpoints parameters: - in: path name: uuid description: '' example: 6218f665-ccd0-417e-917a-faecaa225bc3 required: true schema: type: string '/api/v1/sa/doc-lib/sections/{section_uuid}/icon': post: summary: 'Upload an icon image for a section.' operationId: uploadAnIconImageForASection description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: file: type: string description: 'The image file to upload as the section icon (max 5MB).' example: modi required: - file delete: summary: 'Remove the icon from a section.' operationId: removeTheIconFromASection description: '' parameters: [] responses: { } tags: - Endpoints parameters: - in: path name: section_uuid description: '' example: 6218f665-ccd0-417e-917a-faecaa225bc3 required: true schema: type: string /api/v1/sa/doc-lib/sections/reorder: post: summary: 'Reorder document library sections.' operationId: reorderDocumentLibrarySections description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: orderedUuids: type: array description: 'Must be a valid UUID.' example: - 7ce2d232-a8f8-347c-a2df-9a70a29e897c items: type: string required: - orderedUuids '/api/v1/sa/doc-lib/sections/{section_uuid}/categories': get: summary: 'List all categories for a section.' operationId: listAllCategoriesForASection description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints post: summary: 'Create a new category within a section.' operationId: createANewCategoryWithinASection description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: name: type: string description: 'The name of the category. Must not be greater than 255 characters.' example: 'Installation Guides' description: type: string description: 'An optional description of the category. Must not be greater than 1000 characters.' example: 'Step-by-step installation guides for field technicians.' nullable: true enabled: type: boolean description: '' example: true nullable: true required: - name parameters: - in: path name: section_uuid description: '' example: 6218f665-ccd0-417e-917a-faecaa225bc3 required: true schema: type: string '/api/v1/sa/doc-lib/sections/{section_uuid}/categories/{uuid}': patch: summary: 'Update an existing category.' operationId: updateAnExistingCategory description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: name: type: string description: 'The updated name of the category. Must not be greater than 255 characters.' example: 'Installation Guides' description: type: string description: 'The updated description of the category. Must not be greater than 1000 characters.' example: 'Step-by-step installation guides for field technicians.' nullable: true enabled: type: boolean description: '' example: true nullable: true required: - name delete: summary: 'Delete a category.' operationId: deleteACategory description: '' parameters: [] responses: { } tags: - Endpoints parameters: - in: path name: section_uuid description: '' example: 6218f665-ccd0-417e-917a-faecaa225bc3 required: true schema: type: string - in: path name: uuid description: '' example: 6d8ce9e4-ee38-432f-b75b-6834ef1d21bd required: true schema: type: string '/api/v1/sa/doc-lib/sections/{section_uuid}/categories/{category_uuid}/icon': post: summary: 'Upload an icon image for a category.' operationId: uploadAnIconImageForACategory description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: file: type: string description: 'The image file to upload as the section icon (max 5MB).' example: excepturi required: - file delete: summary: 'Remove the icon from a category.' operationId: removeTheIconFromACategory description: '' parameters: [] responses: { } tags: - Endpoints parameters: - in: path name: section_uuid description: '' example: 6218f665-ccd0-417e-917a-faecaa225bc3 required: true schema: type: string - in: path name: category_uuid description: '' example: 6d8ce9e4-ee38-432f-b75b-6834ef1d21bd required: true schema: type: string '/api/v1/sa/doc-lib/sections/{section_uuid}/categories/reorder': post: summary: 'Reorder categories within a section.' operationId: reorderCategoriesWithinASection description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: orderedUuids: type: array description: 'Must be a valid UUID.' example: - 86f07b5d-baf1-345f-b6ad-1e546ea72580 items: type: string required: - orderedUuids parameters: - in: path name: section_uuid description: '' example: 6218f665-ccd0-417e-917a-faecaa225bc3 required: true schema: type: string '/api/v1/sa/doc-lib/sections/{section_uuid}/categories/{category_uuid}/move': post: summary: 'Move a category to a different section.' operationId: moveACategoryToADifferentSection description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: sectionUuid: type: string description: 'The UUID of the target section to move the category to. Must be a valid UUID. The uuid of an existing record in the document_section table.' example: 550e8400-e29b-41d4-a716-446655440000 required: - sectionUuid parameters: - in: path name: section_uuid description: '' example: 6218f665-ccd0-417e-917a-faecaa225bc3 required: true schema: type: string - in: path name: category_uuid description: '' example: 6d8ce9e4-ee38-432f-b75b-6834ef1d21bd required: true schema: type: string '/api/v1/sa/doc-lib/sections/{section_uuid}/categories/{category_uuid}/documents': get: summary: 'List all documents for a category.' operationId: listAllDocumentsForACategory description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints post: summary: 'Upload a new document into a category.' operationId: uploadANewDocumentIntoACategory description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: multipart/form-data: schema: type: object properties: file: type: string format: binary description: 'The document file to upload (max 64MB). Must be a file. Must not be greater than 65536 kilobytes.' name: type: string description: 'The display name of the document. Must not be greater than 255 characters.' example: 'NCU Installation Manual v2.1' description: type: string description: 'An optional description of the document. Must not be greater than 2000 characters.' example: 'Complete installation and commissioning guide for NCU v2 units.' nullable: true enabled: type: boolean description: 'Whether the document is visible to non-SA users. Defaults to true.' example: true nullable: true required: - file - name parameters: - in: path name: section_uuid description: '' example: 6218f665-ccd0-417e-917a-faecaa225bc3 required: true schema: type: string - in: path name: category_uuid description: '' example: 6d8ce9e4-ee38-432f-b75b-6834ef1d21bd required: true schema: type: string '/api/v1/sa/doc-lib/sections/{section_uuid}/categories/{category_uuid}/documents/{documentSectionDocument_uuid}/icon': post: summary: 'Upload an icon image for a document record.' operationId: uploadAnIconImageForADocumentRecord description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: file: type: string description: 'The image file to upload as the section icon (max 5MB).' example: aut required: - file delete: summary: 'Remove the icon from a document record.' operationId: removeTheIconFromADocumentRecord description: '' parameters: [] responses: { } tags: - Endpoints parameters: - in: path name: section_uuid description: '' example: 6218f665-ccd0-417e-917a-faecaa225bc3 required: true schema: type: string - in: path name: category_uuid description: '' example: 6d8ce9e4-ee38-432f-b75b-6834ef1d21bd required: true schema: type: string - in: path name: documentSectionDocument_uuid description: '' example: ccee35e3-6359-4d97-80cc-bca275fc26cf required: true schema: type: string '/api/v1/sa/doc-lib/sections/{section_uuid}/categories/{category_uuid}/documents/{documentSectionDocument_uuid}': patch: summary: 'Update document metadata.' operationId: updateDocumentMetadata description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: name: type: string description: 'The updated display name of the document. Must not be greater than 255 characters.' example: 'NCU Installation Manual v2.1' description: type: string description: 'The updated description of the document. Must not be greater than 2000 characters.' example: 'Complete installation and commissioning guide for NCU v2 units.' nullable: true enabled: type: boolean description: 'Whether the document is visible to non-SA users.' example: true nullable: true required: - name delete: summary: 'Delete a document.' operationId: deleteADocument description: '' parameters: [] responses: { } tags: - Endpoints parameters: - in: path name: section_uuid description: '' example: 6218f665-ccd0-417e-917a-faecaa225bc3 required: true schema: type: string - in: path name: category_uuid description: '' example: 6d8ce9e4-ee38-432f-b75b-6834ef1d21bd required: true schema: type: string - in: path name: documentSectionDocument_uuid description: '' example: ccee35e3-6359-4d97-80cc-bca275fc26cf required: true schema: type: string '/api/v1/sa/doc-lib/sections/{section_uuid}/categories/{category_uuid}/documents/{documentSectionDocument_uuid}/move': post: summary: 'Move a document to a different category.' operationId: moveADocumentToADifferentCategory description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: categoryUuid: type: string description: 'The UUID of the target category to move the document to. Must be a valid UUID. The uuid of an existing record in the document_section_category table.' example: 6ba7b810-9dad-11d1-80b4-00c04fd430c8 required: - categoryUuid parameters: - in: path name: section_uuid description: '' example: 6218f665-ccd0-417e-917a-faecaa225bc3 required: true schema: type: string - in: path name: category_uuid description: '' example: 6d8ce9e4-ee38-432f-b75b-6834ef1d21bd required: true schema: type: string - in: path name: documentSectionDocument_uuid description: '' example: ccee35e3-6359-4d97-80cc-bca275fc26cf required: true schema: type: string '/api/v1/sa/companies/{company_slug}/firmware-keys': get: summary: '' operationId: getApiV1SaCompaniesCompany_slugFirmwareKeys description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints post: summary: '' operationId: postApiV1SaCompaniesCompany_slugFirmwareKeys description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: name: type: string description: 'Name for the firmware access key. Must not be greater than 255 characters.' example: 'Production Farm Key' description: type: string description: 'Description of the key purpose.' example: 'Key for firmware updates on production farm' nullable: true farmUuid: type: string description: 'UUID of the farm to create the key for. Must be a valid UUID.' example: 550e8400-e29b-41d4-a716-446655440000 expiresAt: type: string description: 'Expiration date for the key. Must be a valid date.' example: '2025-12-31' nullable: true isActive: type: boolean description: 'Whether the key is active.' example: true required: - name - farmUuid parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string '/api/v1/sa/companies/{company_slug}/firmware-keys/{firmwareAccessKey_uuid}': get: summary: '' operationId: getApiV1SaCompaniesCompany_slugFirmwareKeysFirmwareAccessKey_uuid description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints put: summary: '' operationId: putApiV1SaCompaniesCompany_slugFirmwareKeysFirmwareAccessKey_uuid description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: false content: application/json: schema: type: object properties: name: type: string description: 'Name for the firmware access key. Must not be greater than 255 characters.' example: 'Updated Farm Key' description: type: string description: 'Description of the key purpose.' example: 'Updated key description' expiresAt: type: string description: 'Expiration date for the key. Must be a valid date.' example: '2026-06-30' nullable: true isActive: type: boolean description: 'Whether the key is active.' example: false parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: firmwareAccessKey_uuid description: '' example: f2c02d5b-8653-47d4-b315-5d073c2da271 required: true schema: type: string '/api/v1/sa/companies/{company_slug}/firmware-keys/{firmwareAccessKey_uuid}/deactivate': put: summary: '' operationId: putApiV1SaCompaniesCompany_slugFirmwareKeysFirmwareAccessKey_uuidDeactivate description: '' parameters: [] responses: { } tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: firmwareAccessKey_uuid description: '' example: f2c02d5b-8653-47d4-b315-5d073c2da271 required: true schema: type: string /api/v1/sa/firmware: get: summary: 'List available firmware versions (global scope)' operationId: listAvailableFirmwareVersionsglobalScope description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints requestBody: required: false content: application/json: schema: type: object properties: deviceModelTypeSlug: type: string description: 'Filter by device model type slug. The slug of an existing record in the device_model_types table.' example: ncu-v2 enabled: type: boolean description: 'Filter by enabled status.' example: true perPage: type: integer description: 'Number of records per page (1-100). Must be at least 1. Must not be greater than 100.' example: 25 post: summary: 'Upload new firmware' operationId: uploadNewFirmware description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: multipart/form-data: schema: type: object properties: file: type: string format: binary description: 'The firmware binary file (max 100MB). Must be a file. Must not be greater than 102400 kilobytes.' version: type: string description: 'Semantic version of the firmware. Must match the regex /^v?\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/. Must not be greater than 50 characters.' example: v1.2.3 deviceModelTypeSlug: type: string description: 'Slug of the target device model type. The slug of an existing record in the device_model_types table.' example: ncu-v2 nullable: true name: type: string description: 'Display name for the firmware. Must not be greater than 255 characters.' example: 'NCU Firmware v1.2.3' nullable: true description: type: string description: 'Description of the firmware release. Must not be greater than 1000 characters.' example: 'Bug fixes and performance improvements' nullable: true required: - file - version '/api/v1/sa/firmware/{slug}': get: summary: 'Show firmware details' operationId: showFirmwareDetails description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints put: summary: 'Update firmware metadata' operationId: updateFirmwareMetadata description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: false content: application/json: schema: type: object properties: tokenRequired: type: boolean description: '' example: false name: type: string description: 'Must not be greater than 255 characters.' example: qlqbdpfwylgxl description: type: string description: 'Must not be greater than 1000 characters.' example: 'Est est quo enim autem reprehenderit.' delete: summary: 'Delete firmware (soft delete)' operationId: deleteFirmwaresoftDelete description: '' parameters: [] responses: { } tags: - Endpoints parameters: - in: path name: slug description: 'The slug of the firmware.' example: nknown required: true schema: type: string '/api/v1/sa/firmware/{firmware_slug}/toggle': put: summary: 'Enable/disable firmware' operationId: enabledisableFirmware description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: enabled: type: boolean description: '' example: false required: - enabled parameters: - in: path name: firmware_slug description: 'The slug of the firmware.' example: nknown required: true schema: type: string '/api/v1/sa/c/{company_slug}/notification-channels': get: summary: '' operationId: getApiV1SaCCompany_slugNotificationChannels description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints post: summary: '' operationId: postApiV1SaCCompany_slugNotificationChannels description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: companySlug: type: string description: 'Company slug for this channel. The slug of an existing record in the companies table.' example: acme-solar farmUuid: type: string description: 'Optional farm UUID for farm-scoped channels. Must be a valid UUID. The uuid of an existing record in the farms table.' example: 550e8400-e29b-41d4-a716-446655440111 nullable: true notificationChannelType: type: string description: 'Notification channel type slug. The slug of an existing record in the notification_channel_types table.' example: email name: type: string description: 'Display name of the notification channel. Must not be greater than 255 characters.' example: 'Ops Email Alerts' required: - companySlug - notificationChannelType - name parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string '/api/v1/sa/c/{company_slug}/notification-channels/{notificationChannel_uuid}': get: summary: '' operationId: getApiV1SaCCompany_slugNotificationChannelsNotificationChannel_uuid description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints put: summary: '' operationId: putApiV1SaCCompany_slugNotificationChannelsNotificationChannel_uuid description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: false content: application/json: schema: type: object properties: notificationChannelType: type: string description: 'Notification channel type slug. The slug of an existing record in the notification_channel_types table.' example: email nullable: true name: type: string description: 'Display name of the notification channel. Must not be greater than 255 characters.' example: 'Operations Alerts' nullable: true delete: summary: '' operationId: deleteApiV1SaCCompany_slugNotificationChannelsNotificationChannel_uuid description: '' parameters: [] responses: { } tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: notificationChannel_uuid description: '' example: 7f7c4196-264c-34bd-a8b9-d4d45d374030 required: true schema: type: string '/api/v1/sa/c/{company_slug}/notification-channels/{notificationChannel_uuid}/emails': post: summary: '' operationId: postApiV1SaCCompany_slugNotificationChannelsNotificationChannel_uuidEmails description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: emailAddress: type: string description: 'Email address to receive notifications. Must be a valid email address. Must not be greater than 255 characters.' example: alerts@example.com required: - emailAddress parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: notificationChannel_uuid description: '' example: f7a32869-a0aa-3e1e-8d47-63f2b0475265 required: true schema: type: string '/api/v1/sa/c/{company_slug}/notification-channels/{notificationChannel_uuid}/push-devices': post: summary: '' operationId: postApiV1SaCCompany_slugNotificationChannelsNotificationChannel_uuidPushDevices description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: mobileDeviceUuid: type: string description: 'UUID of the mobile device to link for push notifications. Must be a valid UUID. The uuid of an existing record in the mobile_devices table.' example: 550e8400-e29b-41d4-a716-446655440000 required: - mobileDeviceUuid parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: notificationChannel_uuid description: '' example: 122221c6-5ee2-3083-b1f5-fec96c8f9292 required: true schema: type: string '/api/v1/sa/c/{company_slug}/notification-channels/{notificationChannel_uuid}/webhooks': post: summary: '' operationId: postApiV1SaCCompany_slugNotificationChannelsNotificationChannel_uuidWebhooks description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: name: type: string description: 'Webhook name. Must not be greater than 255 characters.' example: 'PagerDuty Webhook' url: type: string description: 'Webhook URL endpoint. Must be a valid URL. Must not be greater than 2048 characters.' example: 'https://hooks.example.com/alerts' httpMethod: type: string description: 'HTTP method used for webhook delivery.' example: POST enum: - POST - PUT - PATCH - DELETE nullable: true timeoutSeconds: type: integer description: 'Webhook timeout in seconds. Must be at least 1. Must not be greater than 120.' example: 30 nullable: true required: - name - url parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: notificationChannel_uuid description: '' example: 4bc73de7-ecf3-3214-a190-785074365fac required: true schema: type: string '/api/v1/sa/c/{company_slug}/notification-channel-emails/{notificationChannelEmail_uuid}': delete: summary: '' operationId: deleteApiV1SaCCompany_slugNotificationChannelEmailsNotificationChannelEmail_uuid description: '' parameters: [] responses: { } tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: notificationChannelEmail_uuid description: '' example: 72f3e884-55a6-3542-93e9-62ceaac23f28 required: true schema: type: string '/api/v1/sa/c/{company_slug}/notification-channel-push-devices/{notificationChannelPushDevice_uuid}': delete: summary: '' operationId: deleteApiV1SaCCompany_slugNotificationChannelPushDevicesNotificationChannelPushDevice_uuid description: '' parameters: [] responses: { } tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: notificationChannelPushDevice_uuid description: '' example: dd55949e-a728-3bda-b5ec-6e022d4a7fb0 required: true schema: type: string '/api/v1/sa/c/{company_slug}/notification-channel-webhooks/{notificationChannelWebhook_uuid}': put: summary: '' operationId: putApiV1SaCCompany_slugNotificationChannelWebhooksNotificationChannelWebhook_uuid description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: false content: application/json: schema: type: object properties: name: type: string description: 'Webhook name. Must not be greater than 255 characters.' example: 'PagerDuty Webhook' nullable: true url: type: string description: 'Webhook URL endpoint. Must be a valid URL. Must not be greater than 2048 characters.' example: 'https://hooks.example.com/alerts' nullable: true httpMethod: type: string description: 'HTTP method used for webhook delivery.' example: PATCH enum: - POST - PUT - PATCH - DELETE nullable: true timeoutSeconds: type: integer description: 'Webhook timeout in seconds. Must be at least 1. Must not be greater than 120.' example: 20 nullable: true delete: summary: '' operationId: deleteApiV1SaCCompany_slugNotificationChannelWebhooksNotificationChannelWebhook_uuid description: '' parameters: [] responses: { } tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: notificationChannelWebhook_uuid description: '' example: 3ce25307-2dbc-33be-bb66-585139140664 required: true schema: type: string '/api/v1/sa/c/{company_slug}/notification-channel-webhooks/{notificationChannelWebhook_uuid}/headers': post: summary: '' operationId: postApiV1SaCCompany_slugNotificationChannelWebhooksNotificationChannelWebhook_uuidHeaders description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: headerKey: type: string description: 'Webhook header key. Must not be greater than 255 characters.' example: X-Signature headerValue: type: string description: 'Webhook header value. Must not be greater than 1000 characters.' example: secret-token required: - headerKey - headerValue parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: notificationChannelWebhook_uuid description: '' example: 54f30de0-9716-38f8-bb64-d32a76684236 required: true schema: type: string '/api/v1/sa/c/{company_slug}/notification-channel-webhook-headers/{notificationChannelWebhookHeader_uuid}': delete: summary: '' operationId: deleteApiV1SaCCompany_slugNotificationChannelWebhookHeadersNotificationChannelWebhookHeader_uuid description: '' parameters: [] responses: { } tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: notificationChannelWebhookHeader_uuid description: '' example: ea780eed-d501-3e67-98da-27887be0ccf5 required: true schema: type: string /api/v1/sa/notification-templates: get: summary: '' operationId: getApiV1SaNotificationTemplates description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints post: summary: '' operationId: postApiV1SaNotificationTemplates description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: notificationChannelType: type: string description: 'Notification channel type slug. The slug of an existing record in the notification_channel_types table.' example: email notificationTemplateFormatType: type: string description: 'Notification template format type slug. The slug of an existing record in the notification_template_format_types table.' example: text name: type: string description: 'Template name. Must not be greater than 255 characters.' example: 'Critical Alert Template' subjectTemplate: type: string description: 'Optional subject template. Supports double-curly-brace placeholders: ruleName, collectorName, triggeredValue, conditionOperator, conditionThreshold, triggeredAt, companyName, farmName. Must not be greater than 500 characters.' example: '[Alert] Collector Offline' nullable: true bodyTemplate: type: string description: 'Template body content. Supports double-curly-brace placeholders: ruleName, collectorName, triggeredValue, conditionOperator, conditionThreshold, triggeredAt, companyName, farmName.' example: 'Alert: Collector went offline at Farm Alpha.' required: - notificationChannelType - notificationTemplateFormatType - name - bodyTemplate '/api/v1/sa/notification-templates/{notificationTemplate_uuid}': get: summary: '' operationId: getApiV1SaNotificationTemplatesNotificationTemplate_uuid description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints put: summary: '' operationId: putApiV1SaNotificationTemplatesNotificationTemplate_uuid description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: false content: application/json: schema: type: object properties: notificationChannelType: type: string description: 'Notification channel type slug. The slug of an existing record in the notification_channel_types table.' example: email nullable: true notificationTemplateFormatType: type: string description: 'Notification template format type slug. The slug of an existing record in the notification_template_format_types table.' example: html nullable: true name: type: string description: 'Template name. Must not be greater than 255 characters.' example: 'Updated Alert Template' nullable: true subjectTemplate: type: string description: 'Optional subject template. Supports double-curly-brace placeholders: ruleName, collectorName, triggeredValue, conditionOperator, conditionThreshold, triggeredAt, companyName, farmName. Must not be greater than 500 characters.' example: '[Updated] Collector Offline' nullable: true bodyTemplate: type: string description: 'Template body content. Supports double-curly-brace placeholders: ruleName, collectorName, triggeredValue, conditionOperator, conditionThreshold, triggeredAt, companyName, farmName.' example: '

Alert rule updated for Collector Alpha.

' nullable: true delete: summary: '' operationId: deleteApiV1SaNotificationTemplatesNotificationTemplate_uuid description: '' parameters: [] responses: { } tags: - Endpoints parameters: - in: path name: notificationTemplate_uuid description: '' example: d4d5b924-eff1-44a7-bcc9-b271d8207888 required: true schema: type: string '/api/v1/sa/c/{company_slug}/notification-policies': get: summary: '' operationId: getApiV1SaCCompany_slugNotificationPolicies description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints post: summary: '' operationId: postApiV1SaCCompany_slugNotificationPolicies description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: companySlug: type: string description: 'Company scope slug. Provide exactly one scope field. The slug of an existing record in the companies table.' example: acme-solar nullable: true farmUuid: type: string description: 'Farm scope UUID. Provide exactly one scope field. Must be a valid UUID. The uuid of an existing record in the farms table.' example: 550e8400-e29b-41d4-a716-446655440121 nullable: true collectorUuid: type: string description: 'Collector scope UUID. Provide exactly one scope field. Must be a valid UUID. The uuid of an existing record in the collectors table.' example: 550e8400-e29b-41d4-a716-446655440122 nullable: true name: type: string description: 'Notification policy name. Must not be greater than 255 characters.' example: 'Critical Weather Policy' enabled: type: boolean description: 'Whether the policy is enabled.' example: true nullable: true notificationChannelUuid: type: string description: 'Notification channel UUID. Must be a valid UUID. The uuid of an existing record in the notification_channels table.' example: 550e8400-e29b-41d4-a716-446655440123 notificationTemplateUuid: type: string description: 'Notification template UUID. Must be a valid UUID. The uuid of an existing record in the notification_templates table.' example: 550e8400-e29b-41d4-a716-446655440124 labels: type: array description: 'Optional key/value label filters.' example: - key: severity value: critical items: type: object nullable: true properties: key: type: string description: 'This field is required when labels is present. Must not be greater than 255 characters.' example: yoosdfdactispddgng value: type: string description: 'This field is required when labels is present. Must not be greater than 255 characters.' example: xpsb required: - name - notificationChannelUuid - notificationTemplateUuid parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string '/api/v1/sa/c/{company_slug}/notification-policies/{notificationPolicy_uuid}': get: summary: '' operationId: getApiV1SaCCompany_slugNotificationPoliciesNotificationPolicy_uuid description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints put: summary: '' operationId: putApiV1SaCCompany_slugNotificationPoliciesNotificationPolicy_uuid description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: false content: application/json: schema: type: object properties: name: type: string description: 'Notification policy name. Must not be greater than 255 characters.' example: 'Critical Weather Policy' nullable: true enabled: type: boolean description: 'Whether the policy is enabled.' example: false nullable: true notificationChannelUuid: type: string description: 'Notification channel UUID. Must be a valid UUID. The uuid of an existing record in the notification_channels table.' example: 550e8400-e29b-41d4-a716-446655440223 nullable: true notificationTemplateUuid: type: string description: 'Notification template UUID. Must be a valid UUID. The uuid of an existing record in the notification_templates table.' example: 550e8400-e29b-41d4-a716-446655440224 nullable: true labels: type: array description: 'Optional key/value label filters.' example: - key: site value: north-farm items: type: object nullable: true properties: key: type: string description: 'This field is required when labels is present. Must not be greater than 255 characters.' example: hgckwvgnncagwsqsqi value: type: string description: 'This field is required when labels is present. Must not be greater than 255 characters.' example: oqersoyuyqw delete: summary: '' operationId: deleteApiV1SaCCompany_slugNotificationPoliciesNotificationPolicy_uuid description: '' parameters: [] responses: { } tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: notificationPolicy_uuid description: '' example: 0d78281c-7fe7-343b-b373-ef3ef026a738 required: true schema: type: string /api/v1/sa/quality-report: get: summary: 'Quality report: failure counts grouped by device model, firmware, and hardware version.' operationId: qualityReportFailureCountsGroupedByDeviceModelFirmwareAndHardwareVersion description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints /api/v1/sa/inventory: get: summary: 'Inventory summary: per-company collector status counts.' operationId: inventorySummaryPerCompanyCollectorStatusCounts description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints /api/v1/sa/rma: get: summary: 'List all RMA requests across all companies.' operationId: listAllRMARequestsAcrossAllCompanies description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints '/api/v1/sa/rma/{rmaRequest_uuid}': get: summary: 'Show a single RMA request with full relations.' operationId: showASingleRMARequestWithFullRelations description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints patch: summary: 'Update the status of an RMA request (intermediate workflow statuses).' operationId: updateTheStatusOfAnRMARequestintermediateWorkflowStatuses description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: status: type: string description: 'Updated super-admin RMA workflow status.' example: diagnosing enum: - shipped-to-vendor - received - diagnosing - repairing notes: type: string description: 'Optional status update notes. Must not be greater than 5000 characters.' example: 'Device received and initial electrical diagnostics started.' nullable: true required: - status parameters: - in: path name: rmaRequest_uuid description: '' example: 9f632600-b90f-3b96-8a31-923a8b9f8811 required: true schema: type: string '/api/v1/sa/rma/{rmaRequest_uuid}/approve': post: summary: 'Approve an RMA request.' operationId: approveAnRMARequest description: '' parameters: [] responses: { } tags: - Endpoints parameters: - in: path name: rmaRequest_uuid description: '' example: ff30af8f-544a-356f-9bc8-c760bd88d80d required: true schema: type: string '/api/v1/sa/rma/{rmaRequest_uuid}/reject': post: summary: 'Reject an RMA request.' operationId: rejectAnRMARequest description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: reason: type: string description: 'Reason the RMA request is being rejected. Must not be greater than 2000 characters.' example: 'Submitted issue does not meet warranty criteria.' required: - reason parameters: - in: path name: rmaRequest_uuid description: '' example: 21440c3d-2fdf-3861-810d-912c4d271136 required: true schema: type: string '/api/v1/sa/rma/{rmaRequest_uuid}/resolve': post: summary: 'Resolve an RMA request (repaired, replaced, or unrepairable).' operationId: resolveAnRMARequestrepairedReplacedOrUnrepairable description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: resolutionType: type: string description: 'Final resolution classification.' example: replaced enum: - repaired - replaced - unrepairable notes: type: string description: 'Resolution summary and service notes. Must not be greater than 5000 characters.' example: 'Unit replaced after diagnostics confirmed controller board failure.' replacementCollectorUuid: type: string description: 'Required when resolutionType is replaced. Must be a valid UUID. The uuid of an existing record in the collectors table.' example: 550e8400-e29b-41d4-a716-446655440110 nullable: true required: - resolutionType - notes parameters: - in: path name: rmaRequest_uuid description: '' example: 6939404e-72fc-363e-aa31-045c5ba1b7d3 required: true schema: type: string '/api/v1/sa/rma/{rmaRequest_uuid}/cancel': post: summary: 'Cancel an RMA request.' operationId: cancelAnRMARequest description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: reason: type: string description: 'Must not be greater than 2000 characters.' example: arfnqxunwpndjcu required: - reason parameters: - in: path name: rmaRequest_uuid description: '' example: d8ef4ca4-8a75-37fe-adc3-2b1c04cebf53 required: true schema: type: string '/api/v1/sa/rma/{rmaRequest_uuid}/notes': get: summary: 'List notes for an RMA request.' operationId: listNotesForAnRMARequest description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints post: summary: 'Add a note to an RMA request.' operationId: addANoteToAnRMARequest description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: note: type: string description: 'Note text to append to the RMA timeline. Must not be greater than 5000 characters.' example: 'Customer confirmed issue is reproducible after reboot.' required: - note parameters: - in: path name: rmaRequest_uuid description: '' example: e7db2fb6-eb2c-3c79-8468-d7b7c6539a24 required: true schema: type: string /api/v1/sa/tracklab/users: get: summary: '' operationId: getApiV1SaTracklabUsers description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints post: summary: '' operationId: postApiV1SaTracklabUsers description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: email: type: string description: 'User email address. Must be a valid email address. Must not be greater than 100 characters.' example: new.user@tracklab.com firstName: type: string description: 'User first name. Must be at least 2 characters. Must not be greater than 100 characters.' example: John lastName: type: string description: 'User last name. Must be at least 2 characters. Must not be greater than 100 characters.' example: Doe countryIsoCode: type: string description: 'ISO country code. The iso_code of an existing record in the countries table.' example: US phoneNumber: type: string description: 'User phone number. Must be at least 6 characters.' example: '+1234567890' role: type: string description: 'User role (owner, admin, or user).' example: admin enum: - admin - owner - user - tracklab-admin - tracklab-support - tracklab-readonly - manager - technician - viewer - external-supplier - external-support - tracklab-dev required: - email - firstName - countryIsoCode - phoneNumber - role '/api/v1/sa/tracklab/users/{user_uuid}': get: summary: '' operationId: getApiV1SaTracklabUsersUser_uuid description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints patch: summary: '' operationId: patchApiV1SaTracklabUsersUser_uuid description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: false content: application/json: schema: type: object properties: email: type: string description: 'User email address. Must be a valid email address. Must not be greater than 100 characters.' example: updated.user@tracklab.com firstName: type: string description: 'User first name. Must be at least 2 characters. Must not be greater than 100 characters.' example: John lastName: type: string description: 'User last name. Must be at least 2 characters. Must not be greater than 100 characters.' example: Smith countryIsoCode: type: string description: 'ISO country code. The iso_code of an existing record in the countries table.' example: US phoneNumber: type: string description: 'User phone number. Must be at least 6 characters.' example: '+1987654321' role: type: string description: 'User role (owner, admin, or user).' example: user enum: - admin - owner - user - tracklab-admin - tracklab-support - tracklab-readonly - manager - technician - viewer - external-supplier - external-support - tracklab-dev delete: summary: '' operationId: deleteApiV1SaTracklabUsersUser_uuid description: '' parameters: [] responses: { } tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: user: type: string description: 'Must be a valid UUID.' example: 47921254-d262-34f7-8bc2-84fd0dc024fe required: - user parameters: - in: path name: user_uuid description: '' example: b11fab33-a56a-4a78-a3c1-b9d324c6aacd required: true schema: type: string /api/v1/sa/warranty/expiring: get: summary: 'List warranties expiring within N days.' operationId: listWarrantiesExpiringWithinNDays description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints /api/v1/health: get: summary: '' operationId: getApiV1Health description: '' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: finishedAt: 1774566311 checkResults: [] properties: finishedAt: type: integer example: 1774566311 checkResults: type: array example: [] tags: - Endpoints /api/v1/firmware/download: get: summary: '' operationId: getApiV1FirmwareDownload description: '' parameters: [] responses: 400: description: '' content: application/json: schema: type: object example: message: 'Firmware slug required' properties: message: type: string example: 'Firmware slug required' tags: - Endpoints '/api/v1/firmware/download/{token}': get: summary: '' operationId: getApiV1FirmwareDownloadToken description: '' parameters: [] responses: 400: description: '' content: application/json: schema: type: object example: message: 'Firmware slug required' properties: message: type: string example: 'Firmware slug required' tags: - Endpoints parameters: - in: path name: token description: '' example: aperiam required: true schema: type: string '/api/v1/open/c/{company_slug}/measurements': get: summary: 'Download measurements using a signed link without authentication.' operationId: downloadMeasurementsUsingASignedLinkWithoutAuthentication description: '' parameters: - in: query name: types description: 'The slug of an existing record in the collector_measurement_types table.' example: - architecto required: false schema: type: array description: 'The slug of an existing record in the collector_measurement_types table.' example: - architecto items: type: string - in: query name: from description: 'Start timestamp (ISO 8601). Must be a valid date. Must be a date before now.' example: '2025-01-01T00:00:00Z' required: true schema: type: string description: 'Start timestamp (ISO 8601). Must be a valid date. Must be a date before now.' example: '2025-01-01T00:00:00Z' - in: query name: collectorUuids description: 'The uuid of an existing record in the collectors table.' example: - quo required: false schema: type: array description: 'The uuid of an existing record in the collectors table.' example: - quo items: type: string - in: query name: farmUuid description: 'Filter by farm UUID. The uuid of an existing record in the farms table.' example: d5b1b4e7-2d71-4c16-9c0c-fc0c2b9f3d0d required: false schema: type: string description: 'Filter by farm UUID. The uuid of an existing record in the farms table.' example: d5b1b4e7-2d71-4c16-9c0c-fc0c2b9f3d0d nullable: true - in: query name: farmSectionUuid description: 'Filter by farm section UUID. The uuid of an existing record in the farm_sections table.' example: 3b3fb893-1e88-4c3c-8b10-0a5c2b3cf6aa required: false schema: type: string description: 'Filter by farm section UUID. The uuid of an existing record in the farm_sections table.' example: 3b3fb893-1e88-4c3c-8b10-0a5c2b3cf6aa nullable: true - in: query name: collectorTypeSlug description: 'Filter by collector type slug. The slug of an existing record in the collector_types table.' example: ncu required: false schema: type: string description: 'Filter by collector type slug. The slug of an existing record in the collector_types table.' example: ncu nullable: true - in: query name: to description: 'End timestamp (ISO 8601). Must be a valid date. Must be a date after from.' example: '2025-01-02T00:00:00Z' required: false schema: type: string description: 'End timestamp (ISO 8601). Must be a valid date. Must be a date after from.' example: '2025-01-02T00:00:00Z' nullable: true - in: query name: raw description: 'When true, returns raw measurements without aggregation.' example: false required: false schema: type: boolean description: 'When true, returns raw measurements without aggregation.' example: false nullable: true - in: query name: period description: 'Aggregation period type slug (when raw=false). The slug of an existing record in the period_types table.' example: minute required: false schema: type: string description: 'Aggregation period type slug (when raw=false). The slug of an existing record in the period_types table.' example: minute nullable: true - in: query name: aggregation description: 'Aggregation method slug (enabled aggregation types only). The slug of an existing record in the measurement_aggregation_types table.' example: avg required: false schema: type: string description: 'Aggregation method slug (enabled aggregation types only). The slug of an existing record in the measurement_aggregation_types table.' example: avg nullable: true - in: query name: valueMin description: 'Minimum measurement value filter.' example: 0.0 required: false schema: type: number description: 'Minimum measurement value filter.' example: 0.0 nullable: true - in: query name: valueMax description: 'Maximum measurement value filter.' example: 1000.0 required: false schema: type: number description: 'Maximum measurement value filter.' example: 1000.0 nullable: true - in: query name: groupBy description: 'Group results by dimension.' example: measurement_type required: false schema: type: string description: 'Group results by dimension.' example: measurement_type enum: - measurement_type - collector - farm_section - time_bucket - tracker nullable: true - in: query name: includeMetadata description: 'Include measurement type / collector metadata.' example: true required: false schema: type: boolean description: 'Include measurement type / collector metadata.' example: true nullable: true - in: query name: includeReplacements description: 'When querying by collector UUIDs, include collector history on the same tracker(s) across handovers.' example: false required: false schema: type: boolean description: 'When querying by collector UUIDs, include collector history on the same tracker(s) across handovers.' example: false nullable: true - in: query name: includeCount description: 'Include total record count per group.' example: false required: false schema: type: boolean description: 'Include total record count per group.' example: false nullable: true - in: query name: exportType description: 'Optional export format.' example: json required: false schema: type: string description: 'Optional export format.' example: json enum: - json - csv - xml - excel nullable: true - in: query name: page description: 'Page number for pagination. Must be at least 1.' example: 1 required: false schema: type: integer description: 'Page number for pagination. Must be at least 1.' example: 1 nullable: true - in: query name: perPage description: 'Items per page (max 10000). Must be at least 1. Must not be greater than 10000.' example: 100 required: false schema: type: integer description: 'Items per page (max 10000). Must be at least 1. Must not be greater than 10000.' example: 100 nullable: true responses: 403: description: '' content: application/json: schema: type: object example: message: 'Invalid signature.' properties: message: type: string example: 'Invalid signature.' tags: - Endpoints parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string '/api/v1/me/profile/picture/{signedToken}/{format}/image.webp': get: summary: 'Get Profile Picture (Signed URL)' operationId: getProfilePictureSignedURL description: "Retrieve a user's profile picture using a signed URL token.\nThe token contains encrypted user UUID and expiry timestamp.\n\nURL format: /me/profile/picture/{signedToken}/{format}/image.webp" parameters: [] responses: 200: description: '' content: text/plain: schema: type: string example: 'The image file stream' 403: description: '' content: application/json: schema: type: object example: message: 'Invalid or expired token.' properties: message: type: string example: 'Invalid or expired token.' 404: description: '' content: application/json: schema: type: object example: message: 'User not found.' properties: message: type: string example: 'User not found.' tags: - Endpoints parameters: - in: path name: signedToken description: 'The encrypted signed token.' example: eyJpdiI6... required: true schema: type: string - in: path name: format description: 'The image format/conversion name.' example: square-48-webp required: true schema: type: string '/api/v1/email/verify/{id}/{hash}': get: summary: '' operationId: getApiV1EmailVerifyIdHash description: '' parameters: [] responses: 403: description: '' content: application/json: schema: type: object example: success: false message: 'Invalid verification link' properties: success: type: boolean example: false message: type: string example: 'Invalid verification link' tags: - Endpoints parameters: - in: path name: id description: 'The ID of the verify.' example: qui required: true schema: type: string - in: path name: hash description: '' example: incidunt required: true schema: type: string '/api/v1/doc-lib/sections/{sectionUuid}/icon/{signedToken}/{format}/image.webp': get: summary: 'Serve a section icon via signed token.' operationId: serveASectionIconViaSignedToken description: 'URL: /api/v1/doc-lib/sections/{sectionUuid}/icon/{signedToken}/{format}/image.webp' parameters: [] responses: 403: description: '' content: application/json: schema: type: object example: message: 'Invalid or expired token.' properties: message: type: string example: 'Invalid or expired token.' tags: - Endpoints parameters: - in: path name: sectionUuid description: '' example: 459c09dc-bdcf-3774-886c-d6e684f68557 required: true schema: type: string - in: path name: signedToken description: '' example: cum required: true schema: type: string - in: path name: format description: '' example: voluptatum required: true schema: type: string '/api/v1/doc-lib/categories/{categoryUuid}/icon/{signedToken}/{format}/image.webp': get: summary: 'Serve a category icon via signed token.' operationId: serveACategoryIconViaSignedToken description: 'URL: /api/v1/doc-lib/categories/{categoryUuid}/icon/{signedToken}/{format}/image.webp' parameters: [] responses: 403: description: '' content: application/json: schema: type: object example: message: 'Invalid or expired token.' properties: message: type: string example: 'Invalid or expired token.' tags: - Endpoints parameters: - in: path name: categoryUuid description: '' example: 3d62664c-fffe-310a-b493-c97303857651 required: true schema: type: string - in: path name: signedToken description: '' example: et required: true schema: type: string - in: path name: format description: '' example: est required: true schema: type: string '/api/v1/doc-lib/documents/{documentSectionDocumentUuid}/icon/{signedToken}/{format}/image.webp': get: summary: 'Serve a document icon via signed token.' operationId: serveADocumentIconViaSignedToken description: 'URL: /api/v1/doc-lib/documents/{documentSectionDocumentUuid}/icon/{signedToken}/{format}/image.webp' parameters: [] responses: 403: description: '' content: application/json: schema: type: object example: message: 'Invalid or expired token.' properties: message: type: string example: 'Invalid or expired token.' tags: - Endpoints parameters: - in: path name: documentSectionDocumentUuid description: '' example: bca27556-039a-39a9-829e-736f095f59ce required: true schema: type: string - in: path name: signedToken description: '' example: eveniet required: true schema: type: string - in: path name: format description: '' example: doloremque required: true schema: type: string '/api/v1/doc-lib/documents/{documentSectionDocumentUuid}/{signedToken}/{format}/file': get: summary: 'Serve a document file via signed token.' operationId: serveADocumentFileViaSignedToken description: 'URL: /api/v1/doc-lib/documents/{documentSectionDocumentUuid}/{signedToken}/{format}/file' parameters: [] responses: 403: description: '' content: application/json: schema: type: object example: message: 'Invalid or expired token.' properties: message: type: string example: 'Invalid or expired token.' tags: - Endpoints parameters: - in: path name: documentSectionDocumentUuid description: '' example: 8fb050a9-44e3-324c-9b2b-0e0b3e838614 required: true schema: type: string - in: path name: signedToken description: '' example: et required: true schema: type: string - in: path name: format description: '' example: sit required: true schema: type: string '/api/v1/c/{companySlug}/automation/webhooks/{automationInboundWebhookSource_uuid}/ingest': post: summary: '' operationId: postApiV1CCompanySlugAutomationWebhooksAutomationInboundWebhookSource_uuidIngest description: '' parameters: [] responses: { } tags: - Endpoints parameters: - in: path name: companySlug description: '' example: officia required: true schema: type: string - in: path name: automationInboundWebhookSource_uuid description: '' example: 03a0e431-35e7-383e-81d5-962acc9f2524 required: true schema: type: string '/api/v1/c/{companySlug}/automation/test/webhook-endpoints/{automationTestWebhookEndpoint_uuid}/ingest': post: summary: '' operationId: postApiV1CCompanySlugAutomationTestWebhookEndpointsAutomationTestWebhookEndpoint_uuidIngest description: '' parameters: [] responses: { } tags: - Endpoints parameters: - in: path name: companySlug description: '' example: magni required: true schema: type: string - in: path name: automationTestWebhookEndpoint_uuid description: '' example: c2f61321-2f80-3814-9e90-9b23fbe6df39 required: true schema: type: string /api/v1/type/automation-action-failure-mode: get: summary: '' operationId: getApiV1TypeAutomationActionFailureMode description: '' parameters: - in: query name: page description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 required: false schema: type: integer description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 - in: query name: perPage description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 required: false schema: type: integer description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 - in: query name: sort description: 'Must not be greater than 255 characters.' example: hbupydlmptqmsdlfl required: false schema: type: string description: 'Must not be greater than 255 characters.' example: hbupydlmptqmsdlfl - in: query name: sortBy description: 'Must not be greater than 255 characters.' example: stugzwgjkywtlopssg required: false schema: type: string description: 'Must not be greater than 255 characters.' example: stugzwgjkywtlopssg - in: query name: sortOrder description: '' example: desc required: false schema: type: string description: '' example: desc enum: - asc - desc - in: query name: filter description: '' example: null required: false schema: type: object description: '' example: null properties: { } - in: query name: filter.search description: 'Must not be greater than 255 characters.' example: bfrmnaregohpwbttlv required: false schema: type: string description: 'Must not be greater than 255 characters.' example: bfrmnaregohpwbttlv - in: query name: filter.active description: '' example: true required: false schema: type: boolean description: '' example: true - in: query name: filter.enabled description: '' example: true required: false schema: type: boolean description: '' example: true responses: 200: description: '' content: application/json: schema: type: object example: data: [] links: first: 'https://tracklabsolar.com/api/v1/type/automation-action-failure-mode?page=1' last: 'https://tracklabsolar.com/api/v1/type/automation-action-failure-mode?page=1' prev: null next: null meta: current_page: 1 from: null last_page: 1 links: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/automation-action-failure-mode?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false path: 'https://tracklabsolar.com/api/v1/type/automation-action-failure-mode' per_page: 20 to: null total: 0 properties: data: type: array example: [] links: type: object properties: first: type: string example: 'https://tracklabsolar.com/api/v1/type/automation-action-failure-mode?page=1' last: type: string example: 'https://tracklabsolar.com/api/v1/type/automation-action-failure-mode?page=1' prev: type: string example: null nullable: true next: type: string example: null nullable: true meta: type: object properties: current_page: type: integer example: 1 from: type: string example: null nullable: true last_page: type: integer example: 1 links: type: array example: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/automation-action-failure-mode?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false items: type: object properties: url: type: string example: null nullable: true label: type: string example: '« Previous' page: type: string example: null nullable: true active: type: boolean example: false path: type: string example: 'https://tracklabsolar.com/api/v1/type/automation-action-failure-mode' per_page: type: integer example: 20 to: type: string example: null nullable: true total: type: integer example: 0 tags: - Endpoints /api/v1/type/automation-action-target: get: summary: '' operationId: getApiV1TypeAutomationActionTarget description: '' parameters: - in: query name: page description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 required: false schema: type: integer description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 - in: query name: perPage description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 required: false schema: type: integer description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 - in: query name: sort description: 'Must not be greater than 255 characters.' example: pr required: false schema: type: string description: 'Must not be greater than 255 characters.' example: pr - in: query name: sortBy description: 'Must not be greater than 255 characters.' example: wiarbrfeaesptqi required: false schema: type: string description: 'Must not be greater than 255 characters.' example: wiarbrfeaesptqi - in: query name: sortOrder description: '' example: desc required: false schema: type: string description: '' example: desc enum: - asc - desc - in: query name: filter description: '' example: null required: false schema: type: object description: '' example: null properties: { } - in: query name: filter.search description: 'Must not be greater than 255 characters.' example: pilgjmekedrnubmcheeb required: false schema: type: string description: 'Must not be greater than 255 characters.' example: pilgjmekedrnubmcheeb - in: query name: filter.active description: '' example: true required: false schema: type: boolean description: '' example: true - in: query name: filter.enabled description: '' example: false required: false schema: type: boolean description: '' example: false responses: 200: description: '' content: application/json: schema: type: object example: data: [] links: first: 'https://tracklabsolar.com/api/v1/type/automation-action-target?page=1' last: 'https://tracklabsolar.com/api/v1/type/automation-action-target?page=1' prev: null next: null meta: current_page: 1 from: null last_page: 1 links: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/automation-action-target?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false path: 'https://tracklabsolar.com/api/v1/type/automation-action-target' per_page: 20 to: null total: 0 properties: data: type: array example: [] links: type: object properties: first: type: string example: 'https://tracklabsolar.com/api/v1/type/automation-action-target?page=1' last: type: string example: 'https://tracklabsolar.com/api/v1/type/automation-action-target?page=1' prev: type: string example: null nullable: true next: type: string example: null nullable: true meta: type: object properties: current_page: type: integer example: 1 from: type: string example: null nullable: true last_page: type: integer example: 1 links: type: array example: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/automation-action-target?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false items: type: object properties: url: type: string example: null nullable: true label: type: string example: '« Previous' page: type: string example: null nullable: true active: type: boolean example: false path: type: string example: 'https://tracklabsolar.com/api/v1/type/automation-action-target' per_page: type: integer example: 20 to: type: string example: null nullable: true total: type: integer example: 0 tags: - Endpoints /api/v1/type/automation-action: get: summary: '' operationId: getApiV1TypeAutomationAction description: '' parameters: - in: query name: page description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 required: false schema: type: integer description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 - in: query name: perPage description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 required: false schema: type: integer description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 - in: query name: sort description: 'Must not be greater than 255 characters.' example: xglsvtouaivycf required: false schema: type: string description: 'Must not be greater than 255 characters.' example: xglsvtouaivycf - in: query name: sortBy description: 'Must not be greater than 255 characters.' example: vqfzystkzuxpygrceasl required: false schema: type: string description: 'Must not be greater than 255 characters.' example: vqfzystkzuxpygrceasl - in: query name: sortOrder description: '' example: desc required: false schema: type: string description: '' example: desc enum: - asc - desc - in: query name: filter description: '' example: null required: false schema: type: object description: '' example: null properties: { } - in: query name: filter.search description: 'Must not be greater than 255 characters.' example: qlgkkyzkuzwbevh required: false schema: type: string description: 'Must not be greater than 255 characters.' example: qlgkkyzkuzwbevh - in: query name: filter.active description: '' example: true required: false schema: type: boolean description: '' example: true - in: query name: filter.enabled description: '' example: true required: false schema: type: boolean description: '' example: true responses: 200: description: '' content: application/json: schema: type: object example: data: [] links: first: 'https://tracklabsolar.com/api/v1/type/automation-action?page=1' last: 'https://tracklabsolar.com/api/v1/type/automation-action?page=1' prev: null next: null meta: current_page: 1 from: null last_page: 1 links: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/automation-action?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false path: 'https://tracklabsolar.com/api/v1/type/automation-action' per_page: 20 to: null total: 0 properties: data: type: array example: [] links: type: object properties: first: type: string example: 'https://tracklabsolar.com/api/v1/type/automation-action?page=1' last: type: string example: 'https://tracklabsolar.com/api/v1/type/automation-action?page=1' prev: type: string example: null nullable: true next: type: string example: null nullable: true meta: type: object properties: current_page: type: integer example: 1 from: type: string example: null nullable: true last_page: type: integer example: 1 links: type: array example: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/automation-action?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false items: type: object properties: url: type: string example: null nullable: true label: type: string example: '« Previous' page: type: string example: null nullable: true active: type: boolean example: false path: type: string example: 'https://tracklabsolar.com/api/v1/type/automation-action' per_page: type: integer example: 20 to: type: string example: null nullable: true total: type: integer example: 0 tags: - Endpoints /api/v1/type/automation-condition-group-operator: get: summary: '' operationId: getApiV1TypeAutomationConditionGroupOperator description: '' parameters: - in: query name: page description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 required: false schema: type: integer description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 - in: query name: perPage description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 required: false schema: type: integer description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 - in: query name: sort description: 'Must not be greater than 255 characters.' example: mlmycabslbflukoh required: false schema: type: string description: 'Must not be greater than 255 characters.' example: mlmycabslbflukoh - in: query name: sortBy description: 'Must not be greater than 255 characters.' example: kotajfvkcoilufyvmyd required: false schema: type: string description: 'Must not be greater than 255 characters.' example: kotajfvkcoilufyvmyd - in: query name: sortOrder description: '' example: asc required: false schema: type: string description: '' example: asc enum: - asc - desc - in: query name: filter description: '' example: null required: false schema: type: object description: '' example: null properties: { } - in: query name: filter.search description: 'Must not be greater than 255 characters.' example: luvpbwohkdudiwyp required: false schema: type: string description: 'Must not be greater than 255 characters.' example: luvpbwohkdudiwyp - in: query name: filter.active description: '' example: true required: false schema: type: boolean description: '' example: true - in: query name: filter.enabled description: '' example: false required: false schema: type: boolean description: '' example: false responses: 200: description: '' content: application/json: schema: type: object example: data: [] links: first: 'https://tracklabsolar.com/api/v1/type/automation-condition-group-operator?page=1' last: 'https://tracklabsolar.com/api/v1/type/automation-condition-group-operator?page=1' prev: null next: null meta: current_page: 1 from: null last_page: 1 links: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/automation-condition-group-operator?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false path: 'https://tracklabsolar.com/api/v1/type/automation-condition-group-operator' per_page: 20 to: null total: 0 properties: data: type: array example: [] links: type: object properties: first: type: string example: 'https://tracklabsolar.com/api/v1/type/automation-condition-group-operator?page=1' last: type: string example: 'https://tracklabsolar.com/api/v1/type/automation-condition-group-operator?page=1' prev: type: string example: null nullable: true next: type: string example: null nullable: true meta: type: object properties: current_page: type: integer example: 1 from: type: string example: null nullable: true last_page: type: integer example: 1 links: type: array example: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/automation-condition-group-operator?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false items: type: object properties: url: type: string example: null nullable: true label: type: string example: '« Previous' page: type: string example: null nullable: true active: type: boolean example: false path: type: string example: 'https://tracklabsolar.com/api/v1/type/automation-condition-group-operator' per_page: type: integer example: 20 to: type: string example: null nullable: true total: type: integer example: 0 tags: - Endpoints /api/v1/type/automation-condition-operator: get: summary: '' operationId: getApiV1TypeAutomationConditionOperator description: '' parameters: - in: query name: page description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 required: false schema: type: integer description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 - in: query name: perPage description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 required: false schema: type: integer description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 - in: query name: sort description: 'Must not be greater than 255 characters.' example: uwabjrkrhjsmowzgytvhg required: false schema: type: string description: 'Must not be greater than 255 characters.' example: uwabjrkrhjsmowzgytvhg - in: query name: sortBy description: 'Must not be greater than 255 characters.' example: hjjdklyfspqucbaplyvhnlff required: false schema: type: string description: 'Must not be greater than 255 characters.' example: hjjdklyfspqucbaplyvhnlff - in: query name: sortOrder description: '' example: asc required: false schema: type: string description: '' example: asc enum: - asc - desc - in: query name: filter description: '' example: null required: false schema: type: object description: '' example: null properties: { } - in: query name: filter.search description: 'Must not be greater than 255 characters.' example: vwzmbmoesnxwbbchjqi required: false schema: type: string description: 'Must not be greater than 255 characters.' example: vwzmbmoesnxwbbchjqi - in: query name: filter.active description: '' example: true required: false schema: type: boolean description: '' example: true - in: query name: filter.enabled description: '' example: false required: false schema: type: boolean description: '' example: false responses: 200: description: '' content: application/json: schema: type: object example: data: [] links: first: 'https://tracklabsolar.com/api/v1/type/automation-condition-operator?page=1' last: 'https://tracklabsolar.com/api/v1/type/automation-condition-operator?page=1' prev: null next: null meta: current_page: 1 from: null last_page: 1 links: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/automation-condition-operator?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false path: 'https://tracklabsolar.com/api/v1/type/automation-condition-operator' per_page: 20 to: null total: 0 properties: data: type: array example: [] links: type: object properties: first: type: string example: 'https://tracklabsolar.com/api/v1/type/automation-condition-operator?page=1' last: type: string example: 'https://tracklabsolar.com/api/v1/type/automation-condition-operator?page=1' prev: type: string example: null nullable: true next: type: string example: null nullable: true meta: type: object properties: current_page: type: integer example: 1 from: type: string example: null nullable: true last_page: type: integer example: 1 links: type: array example: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/automation-condition-operator?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false items: type: object properties: url: type: string example: null nullable: true label: type: string example: '« Previous' page: type: string example: null nullable: true active: type: boolean example: false path: type: string example: 'https://tracklabsolar.com/api/v1/type/automation-condition-operator' per_page: type: integer example: 20 to: type: string example: null nullable: true total: type: integer example: 0 tags: - Endpoints /api/v1/type/automation-event-source: get: summary: '' operationId: getApiV1TypeAutomationEventSource description: '' parameters: - in: query name: page description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 required: false schema: type: integer description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 - in: query name: perPage description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 required: false schema: type: integer description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 - in: query name: sort description: 'Must not be greater than 255 characters.' example: eoejvnqsmfu required: false schema: type: string description: 'Must not be greater than 255 characters.' example: eoejvnqsmfu - in: query name: sortBy description: 'Must not be greater than 255 characters.' example: grwgqrfarayd required: false schema: type: string description: 'Must not be greater than 255 characters.' example: grwgqrfarayd - in: query name: sortOrder description: '' example: desc required: false schema: type: string description: '' example: desc enum: - asc - desc - in: query name: filter description: '' example: null required: false schema: type: object description: '' example: null properties: { } - in: query name: filter.search description: 'Must not be greater than 255 characters.' example: nnecwug required: false schema: type: string description: 'Must not be greater than 255 characters.' example: nnecwug - in: query name: filter.active description: '' example: false required: false schema: type: boolean description: '' example: false - in: query name: filter.enabled description: '' example: false required: false schema: type: boolean description: '' example: false responses: 200: description: '' content: application/json: schema: type: object example: data: [] links: first: 'https://tracklabsolar.com/api/v1/type/automation-event-source?page=1' last: 'https://tracklabsolar.com/api/v1/type/automation-event-source?page=1' prev: null next: null meta: current_page: 1 from: null last_page: 1 links: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/automation-event-source?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false path: 'https://tracklabsolar.com/api/v1/type/automation-event-source' per_page: 20 to: null total: 0 properties: data: type: array example: [] links: type: object properties: first: type: string example: 'https://tracklabsolar.com/api/v1/type/automation-event-source?page=1' last: type: string example: 'https://tracklabsolar.com/api/v1/type/automation-event-source?page=1' prev: type: string example: null nullable: true next: type: string example: null nullable: true meta: type: object properties: current_page: type: integer example: 1 from: type: string example: null nullable: true last_page: type: integer example: 1 links: type: array example: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/automation-event-source?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false items: type: object properties: url: type: string example: null nullable: true label: type: string example: '« Previous' page: type: string example: null nullable: true active: type: boolean example: false path: type: string example: 'https://tracklabsolar.com/api/v1/type/automation-event-source' per_page: type: integer example: 20 to: type: string example: null nullable: true total: type: integer example: 0 tags: - Endpoints /api/v1/type/automation-event-status: get: summary: '' operationId: getApiV1TypeAutomationEventStatus description: '' parameters: - in: query name: page description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 required: false schema: type: integer description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 - in: query name: perPage description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 required: false schema: type: integer description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 - in: query name: sort description: 'Must not be greater than 255 characters.' example: hjitwrqrlenurq required: false schema: type: string description: 'Must not be greater than 255 characters.' example: hjitwrqrlenurq - in: query name: sortBy description: 'Must not be greater than 255 characters.' example: kkcnudsbefguvrkd required: false schema: type: string description: 'Must not be greater than 255 characters.' example: kkcnudsbefguvrkd - in: query name: sortOrder description: '' example: asc required: false schema: type: string description: '' example: asc enum: - asc - desc - in: query name: filter description: '' example: null required: false schema: type: object description: '' example: null properties: { } - in: query name: filter.search description: 'Must not be greater than 255 characters.' example: ewzduyhtbzpydi required: false schema: type: string description: 'Must not be greater than 255 characters.' example: ewzduyhtbzpydi - in: query name: filter.active description: '' example: false required: false schema: type: boolean description: '' example: false - in: query name: filter.enabled description: '' example: false required: false schema: type: boolean description: '' example: false responses: 200: description: '' content: application/json: schema: type: object example: data: [] links: first: 'https://tracklabsolar.com/api/v1/type/automation-event-status?page=1' last: 'https://tracklabsolar.com/api/v1/type/automation-event-status?page=1' prev: null next: null meta: current_page: 1 from: null last_page: 1 links: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/automation-event-status?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false path: 'https://tracklabsolar.com/api/v1/type/automation-event-status' per_page: 20 to: null total: 0 properties: data: type: array example: [] links: type: object properties: first: type: string example: 'https://tracklabsolar.com/api/v1/type/automation-event-status?page=1' last: type: string example: 'https://tracklabsolar.com/api/v1/type/automation-event-status?page=1' prev: type: string example: null nullable: true next: type: string example: null nullable: true meta: type: object properties: current_page: type: integer example: 1 from: type: string example: null nullable: true last_page: type: integer example: 1 links: type: array example: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/automation-event-status?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false items: type: object properties: url: type: string example: null nullable: true label: type: string example: '« Previous' page: type: string example: null nullable: true active: type: boolean example: false path: type: string example: 'https://tracklabsolar.com/api/v1/type/automation-event-status' per_page: type: integer example: 20 to: type: string example: null nullable: true total: type: integer example: 0 tags: - Endpoints /api/v1/type/automation-execution-status: get: summary: '' operationId: getApiV1TypeAutomationExecutionStatus description: '' parameters: - in: query name: page description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 required: false schema: type: integer description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 - in: query name: perPage description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 required: false schema: type: integer description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 - in: query name: sort description: 'Must not be greater than 255 characters.' example: mydqcbmqpmbrqukvkpydhsj required: false schema: type: string description: 'Must not be greater than 255 characters.' example: mydqcbmqpmbrqukvkpydhsj - in: query name: sortBy description: 'Must not be greater than 255 characters.' example: gjwparvbacqfmhoryoomh required: false schema: type: string description: 'Must not be greater than 255 characters.' example: gjwparvbacqfmhoryoomh - in: query name: sortOrder description: '' example: desc required: false schema: type: string description: '' example: desc enum: - asc - desc - in: query name: filter description: '' example: null required: false schema: type: object description: '' example: null properties: { } - in: query name: filter.search description: 'Must not be greater than 255 characters.' example: o required: false schema: type: string description: 'Must not be greater than 255 characters.' example: o - in: query name: filter.active description: '' example: false required: false schema: type: boolean description: '' example: false - in: query name: filter.enabled description: '' example: true required: false schema: type: boolean description: '' example: true responses: 200: description: '' content: application/json: schema: type: object example: data: [] links: first: 'https://tracklabsolar.com/api/v1/type/automation-execution-status?page=1' last: 'https://tracklabsolar.com/api/v1/type/automation-execution-status?page=1' prev: null next: null meta: current_page: 1 from: null last_page: 1 links: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/automation-execution-status?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false path: 'https://tracklabsolar.com/api/v1/type/automation-execution-status' per_page: 20 to: null total: 0 properties: data: type: array example: [] links: type: object properties: first: type: string example: 'https://tracklabsolar.com/api/v1/type/automation-execution-status?page=1' last: type: string example: 'https://tracklabsolar.com/api/v1/type/automation-execution-status?page=1' prev: type: string example: null nullable: true next: type: string example: null nullable: true meta: type: object properties: current_page: type: integer example: 1 from: type: string example: null nullable: true last_page: type: integer example: 1 links: type: array example: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/automation-execution-status?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false items: type: object properties: url: type: string example: null nullable: true label: type: string example: '« Previous' page: type: string example: null nullable: true active: type: boolean example: false path: type: string example: 'https://tracklabsolar.com/api/v1/type/automation-execution-status' per_page: type: integer example: 20 to: type: string example: null nullable: true total: type: integer example: 0 tags: - Endpoints /api/v1/type/automation-match-status: get: summary: '' operationId: getApiV1TypeAutomationMatchStatus description: '' parameters: - in: query name: page description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 required: false schema: type: integer description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 - in: query name: perPage description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 required: false schema: type: integer description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 - in: query name: sort description: 'Must not be greater than 255 characters.' example: klnagvpoiobqttvrymcqbnqbu required: false schema: type: string description: 'Must not be greater than 255 characters.' example: klnagvpoiobqttvrymcqbnqbu - in: query name: sortBy description: 'Must not be greater than 255 characters.' example: nrcszlkyuoswtgh required: false schema: type: string description: 'Must not be greater than 255 characters.' example: nrcszlkyuoswtgh - in: query name: sortOrder description: '' example: desc required: false schema: type: string description: '' example: desc enum: - asc - desc - in: query name: filter description: '' example: null required: false schema: type: object description: '' example: null properties: { } - in: query name: filter.search description: 'Must not be greater than 255 characters.' example: mctoafrvwd required: false schema: type: string description: 'Must not be greater than 255 characters.' example: mctoafrvwd - in: query name: filter.active description: '' example: false required: false schema: type: boolean description: '' example: false - in: query name: filter.enabled description: '' example: true required: false schema: type: boolean description: '' example: true responses: 200: description: '' content: application/json: schema: type: object example: data: [] links: first: 'https://tracklabsolar.com/api/v1/type/automation-match-status?page=1' last: 'https://tracklabsolar.com/api/v1/type/automation-match-status?page=1' prev: null next: null meta: current_page: 1 from: null last_page: 1 links: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/automation-match-status?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false path: 'https://tracklabsolar.com/api/v1/type/automation-match-status' per_page: 20 to: null total: 0 properties: data: type: array example: [] links: type: object properties: first: type: string example: 'https://tracklabsolar.com/api/v1/type/automation-match-status?page=1' last: type: string example: 'https://tracklabsolar.com/api/v1/type/automation-match-status?page=1' prev: type: string example: null nullable: true next: type: string example: null nullable: true meta: type: object properties: current_page: type: integer example: 1 from: type: string example: null nullable: true last_page: type: integer example: 1 links: type: array example: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/automation-match-status?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false items: type: object properties: url: type: string example: null nullable: true label: type: string example: '« Previous' page: type: string example: null nullable: true active: type: boolean example: false path: type: string example: 'https://tracklabsolar.com/api/v1/type/automation-match-status' per_page: type: integer example: 20 to: type: string example: null nullable: true total: type: integer example: 0 tags: - Endpoints /api/v1/type/automation-rule-status: get: summary: '' operationId: getApiV1TypeAutomationRuleStatus description: '' parameters: - in: query name: page description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 required: false schema: type: integer description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 - in: query name: perPage description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 required: false schema: type: integer description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 - in: query name: sort description: 'Must not be greater than 255 characters.' example: vxoxcldiyvbnf required: false schema: type: string description: 'Must not be greater than 255 characters.' example: vxoxcldiyvbnf - in: query name: sortBy description: 'Must not be greater than 255 characters.' example: ia required: false schema: type: string description: 'Must not be greater than 255 characters.' example: ia - in: query name: sortOrder description: '' example: asc required: false schema: type: string description: '' example: asc enum: - asc - desc - in: query name: filter description: '' example: null required: false schema: type: object description: '' example: null properties: { } - in: query name: filter.search description: 'Must not be greater than 255 characters.' example: lpymxo required: false schema: type: string description: 'Must not be greater than 255 characters.' example: lpymxo - in: query name: filter.active description: '' example: true required: false schema: type: boolean description: '' example: true - in: query name: filter.enabled description: '' example: false required: false schema: type: boolean description: '' example: false responses: 200: description: '' content: application/json: schema: type: object example: data: [] links: first: 'https://tracklabsolar.com/api/v1/type/automation-rule-status?page=1' last: 'https://tracklabsolar.com/api/v1/type/automation-rule-status?page=1' prev: null next: null meta: current_page: 1 from: null last_page: 1 links: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/automation-rule-status?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false path: 'https://tracklabsolar.com/api/v1/type/automation-rule-status' per_page: 20 to: null total: 0 properties: data: type: array example: [] links: type: object properties: first: type: string example: 'https://tracklabsolar.com/api/v1/type/automation-rule-status?page=1' last: type: string example: 'https://tracklabsolar.com/api/v1/type/automation-rule-status?page=1' prev: type: string example: null nullable: true next: type: string example: null nullable: true meta: type: object properties: current_page: type: integer example: 1 from: type: string example: null nullable: true last_page: type: integer example: 1 links: type: array example: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/automation-rule-status?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false items: type: object properties: url: type: string example: null nullable: true label: type: string example: '« Previous' page: type: string example: null nullable: true active: type: boolean example: false path: type: string example: 'https://tracklabsolar.com/api/v1/type/automation-rule-status' per_page: type: integer example: 20 to: type: string example: null nullable: true total: type: integer example: 0 tags: - Endpoints /api/v1/type/automation-trigger-subject: get: summary: '' operationId: getApiV1TypeAutomationTriggerSubject description: '' parameters: - in: query name: page description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 required: false schema: type: integer description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 - in: query name: perPage description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 required: false schema: type: integer description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 - in: query name: sort description: 'Must not be greater than 255 characters.' example: tebwfsjohuuzhodzxeg required: false schema: type: string description: 'Must not be greater than 255 characters.' example: tebwfsjohuuzhodzxeg - in: query name: sortBy description: 'Must not be greater than 255 characters.' example: cpxyhhkynoigodsbhkyjsuuce required: false schema: type: string description: 'Must not be greater than 255 characters.' example: cpxyhhkynoigodsbhkyjsuuce - in: query name: sortOrder description: '' example: desc required: false schema: type: string description: '' example: desc enum: - asc - desc - in: query name: filter description: '' example: null required: false schema: type: object description: '' example: null properties: { } - in: query name: filter.search description: 'Must not be greater than 255 characters.' example: ihrp required: false schema: type: string description: 'Must not be greater than 255 characters.' example: ihrp - in: query name: filter.active description: '' example: true required: false schema: type: boolean description: '' example: true - in: query name: filter.enabled description: '' example: true required: false schema: type: boolean description: '' example: true responses: 200: description: '' content: application/json: schema: type: object example: data: [] links: first: 'https://tracklabsolar.com/api/v1/type/automation-trigger-subject?page=1' last: 'https://tracklabsolar.com/api/v1/type/automation-trigger-subject?page=1' prev: null next: null meta: current_page: 1 from: null last_page: 1 links: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/automation-trigger-subject?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false path: 'https://tracklabsolar.com/api/v1/type/automation-trigger-subject' per_page: 20 to: null total: 0 properties: data: type: array example: [] links: type: object properties: first: type: string example: 'https://tracklabsolar.com/api/v1/type/automation-trigger-subject?page=1' last: type: string example: 'https://tracklabsolar.com/api/v1/type/automation-trigger-subject?page=1' prev: type: string example: null nullable: true next: type: string example: null nullable: true meta: type: object properties: current_page: type: integer example: 1 from: type: string example: null nullable: true last_page: type: integer example: 1 links: type: array example: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/automation-trigger-subject?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false items: type: object properties: url: type: string example: null nullable: true label: type: string example: '« Previous' page: type: string example: null nullable: true active: type: boolean example: false path: type: string example: 'https://tracklabsolar.com/api/v1/type/automation-trigger-subject' per_page: type: integer example: 20 to: type: string example: null nullable: true total: type: integer example: 0 tags: - Endpoints /api/v1/type/automation-weather-metric: get: summary: '' operationId: getApiV1TypeAutomationWeatherMetric description: '' parameters: - in: query name: page description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 required: false schema: type: integer description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 - in: query name: perPage description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 required: false schema: type: integer description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 - in: query name: sort description: 'Must not be greater than 255 characters.' example: ructtx required: false schema: type: string description: 'Must not be greater than 255 characters.' example: ructtx - in: query name: sortBy description: 'Must not be greater than 255 characters.' example: zwmbcowfsauognk required: false schema: type: string description: 'Must not be greater than 255 characters.' example: zwmbcowfsauognk - in: query name: sortOrder description: '' example: asc required: false schema: type: string description: '' example: asc enum: - asc - desc - in: query name: filter description: '' example: null required: false schema: type: object description: '' example: null properties: { } - in: query name: filter.search description: 'Must not be greater than 255 characters.' example: e required: false schema: type: string description: 'Must not be greater than 255 characters.' example: e - in: query name: filter.active description: '' example: false required: false schema: type: boolean description: '' example: false - in: query name: filter.enabled description: '' example: true required: false schema: type: boolean description: '' example: true responses: 200: description: '' content: application/json: schema: type: object example: data: - slug: wind-speed name: 'Wind Speed' description: '' - slug: temperature name: Temperature description: '' links: first: 'https://tracklabsolar.com/api/v1/type/automation-weather-metric?page=1' last: 'https://tracklabsolar.com/api/v1/type/automation-weather-metric?page=1' prev: null next: null meta: current_page: 1 from: 1 last_page: 1 links: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/automation-weather-metric?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false path: 'https://tracklabsolar.com/api/v1/type/automation-weather-metric' per_page: 20 to: 2 total: 2 properties: data: type: array example: - slug: wind-speed name: 'Wind Speed' description: '' - slug: temperature name: Temperature description: '' items: type: object properties: slug: type: string example: wind-speed name: type: string example: 'Wind Speed' description: type: string example: '' links: type: object properties: first: type: string example: 'https://tracklabsolar.com/api/v1/type/automation-weather-metric?page=1' last: type: string example: 'https://tracklabsolar.com/api/v1/type/automation-weather-metric?page=1' prev: type: string example: null nullable: true next: type: string example: null nullable: true meta: type: object properties: current_page: type: integer example: 1 from: type: integer example: 1 last_page: type: integer example: 1 links: type: array example: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/automation-weather-metric?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false items: type: object properties: url: type: string example: null nullable: true label: type: string example: '« Previous' page: type: string example: null nullable: true active: type: boolean example: false path: type: string example: 'https://tracklabsolar.com/api/v1/type/automation-weather-metric' per_page: type: integer example: 20 to: type: integer example: 2 total: type: integer example: 2 tags: - Endpoints /api/v1/type/automation-webhook-auth: get: summary: '' operationId: getApiV1TypeAutomationWebhookAuth description: '' parameters: - in: query name: page description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 required: false schema: type: integer description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 - in: query name: perPage description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 required: false schema: type: integer description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 - in: query name: sort description: 'Must not be greater than 255 characters.' example: mgcovdkwswvfm required: false schema: type: string description: 'Must not be greater than 255 characters.' example: mgcovdkwswvfm - in: query name: sortBy description: 'Must not be greater than 255 characters.' example: qmxiynklwrgqlbcdvxeu required: false schema: type: string description: 'Must not be greater than 255 characters.' example: qmxiynklwrgqlbcdvxeu - in: query name: sortOrder description: '' example: asc required: false schema: type: string description: '' example: asc enum: - asc - desc - in: query name: filter description: '' example: null required: false schema: type: object description: '' example: null properties: { } - in: query name: filter.search description: 'Must not be greater than 255 characters.' example: bldrgofxvwokadwvfjtfi required: false schema: type: string description: 'Must not be greater than 255 characters.' example: bldrgofxvwokadwvfjtfi - in: query name: filter.active description: '' example: true required: false schema: type: boolean description: '' example: true - in: query name: filter.enabled description: '' example: true required: false schema: type: boolean description: '' example: true responses: 200: description: '' content: application/json: schema: type: object example: data: [] links: first: 'https://tracklabsolar.com/api/v1/type/automation-webhook-auth?page=1' last: 'https://tracklabsolar.com/api/v1/type/automation-webhook-auth?page=1' prev: null next: null meta: current_page: 1 from: null last_page: 1 links: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/automation-webhook-auth?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false path: 'https://tracklabsolar.com/api/v1/type/automation-webhook-auth' per_page: 20 to: null total: 0 properties: data: type: array example: [] links: type: object properties: first: type: string example: 'https://tracklabsolar.com/api/v1/type/automation-webhook-auth?page=1' last: type: string example: 'https://tracklabsolar.com/api/v1/type/automation-webhook-auth?page=1' prev: type: string example: null nullable: true next: type: string example: null nullable: true meta: type: object properties: current_page: type: integer example: 1 from: type: string example: null nullable: true last_page: type: integer example: 1 links: type: array example: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/automation-webhook-auth?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false items: type: object properties: url: type: string example: null nullable: true label: type: string example: '« Previous' page: type: string example: null nullable: true active: type: boolean example: false path: type: string example: 'https://tracklabsolar.com/api/v1/type/automation-webhook-auth' per_page: type: integer example: 20 to: type: string example: null nullable: true total: type: integer example: 0 tags: - Endpoints /api/v1/type/collector: get: summary: '' operationId: getApiV1TypeCollector description: '' parameters: - in: query name: page description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 required: false schema: type: integer description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 - in: query name: perPage description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 required: false schema: type: integer description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 - in: query name: sort description: 'Must not be greater than 255 characters.' example: egloxwobcvyvnuxcji required: false schema: type: string description: 'Must not be greater than 255 characters.' example: egloxwobcvyvnuxcji - in: query name: sortBy description: 'Must not be greater than 255 characters.' example: h required: false schema: type: string description: 'Must not be greater than 255 characters.' example: h - in: query name: sortOrder description: '' example: desc required: false schema: type: string description: '' example: desc enum: - asc - desc - in: query name: filter description: '' example: null required: false schema: type: object description: '' example: null properties: { } - in: query name: filter.search description: 'Must not be greater than 255 characters.' example: jxdrwcelmfbrfshxa required: false schema: type: string description: 'Must not be greater than 255 characters.' example: jxdrwcelmfbrfshxa - in: query name: filter.active description: '' example: false required: false schema: type: boolean description: '' example: false - in: query name: filter.enabled description: '' example: true required: false schema: type: boolean description: '' example: true responses: 200: description: '' content: application/json: schema: type: object example: data: [] links: first: 'https://tracklabsolar.com/api/v1/type/collector?page=1' last: 'https://tracklabsolar.com/api/v1/type/collector?page=1' prev: null next: null meta: current_page: 1 from: null last_page: 1 links: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/collector?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false path: 'https://tracklabsolar.com/api/v1/type/collector' per_page: 20 to: null total: 0 properties: data: type: array example: [] links: type: object properties: first: type: string example: 'https://tracklabsolar.com/api/v1/type/collector?page=1' last: type: string example: 'https://tracklabsolar.com/api/v1/type/collector?page=1' prev: type: string example: null nullable: true next: type: string example: null nullable: true meta: type: object properties: current_page: type: integer example: 1 from: type: string example: null nullable: true last_page: type: integer example: 1 links: type: array example: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/collector?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false items: type: object properties: url: type: string example: null nullable: true label: type: string example: '« Previous' page: type: string example: null nullable: true active: type: boolean example: false path: type: string example: 'https://tracklabsolar.com/api/v1/type/collector' per_page: type: integer example: 20 to: type: string example: null nullable: true total: type: integer example: 0 tags: - Endpoints /api/v1/type/collector-status: get: summary: '' operationId: getApiV1TypeCollectorStatus description: '' parameters: - in: query name: page description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 required: false schema: type: integer description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 - in: query name: perPage description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 required: false schema: type: integer description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 - in: query name: sort description: 'Must not be greater than 255 characters.' example: gwobdxuhdyngs required: false schema: type: string description: 'Must not be greater than 255 characters.' example: gwobdxuhdyngs - in: query name: sortBy description: 'Must not be greater than 255 characters.' example: vujkqaeotloqtbmbkhmghsgtw required: false schema: type: string description: 'Must not be greater than 255 characters.' example: vujkqaeotloqtbmbkhmghsgtw - in: query name: sortOrder description: '' example: desc required: false schema: type: string description: '' example: desc enum: - asc - desc - in: query name: filter description: '' example: null required: false schema: type: object description: '' example: null properties: { } - in: query name: filter.search description: 'Must not be greater than 255 characters.' example: snyb required: false schema: type: string description: 'Must not be greater than 255 characters.' example: snyb - in: query name: filter.active description: '' example: false required: false schema: type: boolean description: '' example: false - in: query name: filter.enabled description: '' example: true required: false schema: type: boolean description: '' example: true responses: 200: description: '' content: application/json: schema: type: object example: data: [] links: first: 'https://tracklabsolar.com/api/v1/type/collector-status?page=1' last: 'https://tracklabsolar.com/api/v1/type/collector-status?page=1' prev: null next: null meta: current_page: 1 from: null last_page: 1 links: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/collector-status?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false path: 'https://tracklabsolar.com/api/v1/type/collector-status' per_page: 20 to: null total: 0 properties: data: type: array example: [] links: type: object properties: first: type: string example: 'https://tracklabsolar.com/api/v1/type/collector-status?page=1' last: type: string example: 'https://tracklabsolar.com/api/v1/type/collector-status?page=1' prev: type: string example: null nullable: true next: type: string example: null nullable: true meta: type: object properties: current_page: type: integer example: 1 from: type: string example: null nullable: true last_page: type: integer example: 1 links: type: array example: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/collector-status?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false items: type: object properties: url: type: string example: null nullable: true label: type: string example: '« Previous' page: type: string example: null nullable: true active: type: boolean example: false path: type: string example: 'https://tracklabsolar.com/api/v1/type/collector-status' per_page: type: integer example: 20 to: type: string example: null nullable: true total: type: integer example: 0 tags: - Endpoints /api/v1/type/company-contact: get: summary: '' operationId: getApiV1TypeCompanyContact description: '' parameters: - in: query name: page description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 required: false schema: type: integer description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 - in: query name: perPage description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 required: false schema: type: integer description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 - in: query name: sort description: 'Must not be greater than 255 characters.' example: apyngluhib required: false schema: type: string description: 'Must not be greater than 255 characters.' example: apyngluhib - in: query name: sortBy description: 'Must not be greater than 255 characters.' example: zrmpcolunq required: false schema: type: string description: 'Must not be greater than 255 characters.' example: zrmpcolunq - in: query name: sortOrder description: '' example: asc required: false schema: type: string description: '' example: asc enum: - asc - desc - in: query name: filter description: '' example: null required: false schema: type: object description: '' example: null properties: { } - in: query name: filter.search description: 'Must not be greater than 255 characters.' example: jh required: false schema: type: string description: 'Must not be greater than 255 characters.' example: jh - in: query name: filter.active description: '' example: true required: false schema: type: boolean description: '' example: true - in: query name: filter.enabled description: '' example: true required: false schema: type: boolean description: '' example: true responses: 200: description: '' content: application/json: schema: type: object example: data: [] links: first: 'https://tracklabsolar.com/api/v1/type/company-contact?page=1' last: 'https://tracklabsolar.com/api/v1/type/company-contact?page=1' prev: null next: null meta: current_page: 1 from: null last_page: 1 links: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/company-contact?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false path: 'https://tracklabsolar.com/api/v1/type/company-contact' per_page: 20 to: null total: 0 properties: data: type: array example: [] links: type: object properties: first: type: string example: 'https://tracklabsolar.com/api/v1/type/company-contact?page=1' last: type: string example: 'https://tracklabsolar.com/api/v1/type/company-contact?page=1' prev: type: string example: null nullable: true next: type: string example: null nullable: true meta: type: object properties: current_page: type: integer example: 1 from: type: string example: null nullable: true last_page: type: integer example: 1 links: type: array example: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/company-contact?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false items: type: object properties: url: type: string example: null nullable: true label: type: string example: '« Previous' page: type: string example: null nullable: true active: type: boolean example: false path: type: string example: 'https://tracklabsolar.com/api/v1/type/company-contact' per_page: type: integer example: 20 to: type: string example: null nullable: true total: type: integer example: 0 tags: - Endpoints /api/v1/type/company-link-invite-status: get: summary: '' operationId: getApiV1TypeCompanyLinkInviteStatus description: '' parameters: - in: query name: page description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 required: false schema: type: integer description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 - in: query name: perPage description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 required: false schema: type: integer description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 - in: query name: sort description: 'Must not be greater than 255 characters.' example: elpufpkem required: false schema: type: string description: 'Must not be greater than 255 characters.' example: elpufpkem - in: query name: sortBy description: 'Must not be greater than 255 characters.' example: fcdjxjffjyyesfvdimcmvwpf required: false schema: type: string description: 'Must not be greater than 255 characters.' example: fcdjxjffjyyesfvdimcmvwpf - in: query name: sortOrder description: '' example: asc required: false schema: type: string description: '' example: asc enum: - asc - desc - in: query name: filter description: '' example: null required: false schema: type: object description: '' example: null properties: { } - in: query name: filter.search description: 'Must not be greater than 255 characters.' example: ocfeuilgtimpn required: false schema: type: string description: 'Must not be greater than 255 characters.' example: ocfeuilgtimpn - in: query name: filter.active description: '' example: false required: false schema: type: boolean description: '' example: false - in: query name: filter.enabled description: '' example: true required: false schema: type: boolean description: '' example: true responses: 200: description: '' content: application/json: schema: type: object example: data: [] links: first: 'https://tracklabsolar.com/api/v1/type/company-link-invite-status?page=1' last: 'https://tracklabsolar.com/api/v1/type/company-link-invite-status?page=1' prev: null next: null meta: current_page: 1 from: null last_page: 1 links: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/company-link-invite-status?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false path: 'https://tracklabsolar.com/api/v1/type/company-link-invite-status' per_page: 20 to: null total: 0 properties: data: type: array example: [] links: type: object properties: first: type: string example: 'https://tracklabsolar.com/api/v1/type/company-link-invite-status?page=1' last: type: string example: 'https://tracklabsolar.com/api/v1/type/company-link-invite-status?page=1' prev: type: string example: null nullable: true next: type: string example: null nullable: true meta: type: object properties: current_page: type: integer example: 1 from: type: string example: null nullable: true last_page: type: integer example: 1 links: type: array example: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/company-link-invite-status?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false items: type: object properties: url: type: string example: null nullable: true label: type: string example: '« Previous' page: type: string example: null nullable: true active: type: boolean example: false path: type: string example: 'https://tracklabsolar.com/api/v1/type/company-link-invite-status' per_page: type: integer example: 20 to: type: string example: null nullable: true total: type: integer example: 0 tags: - Endpoints /api/v1/type/company-link-status: get: summary: '' operationId: getApiV1TypeCompanyLinkStatus description: '' parameters: - in: query name: page description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 required: false schema: type: integer description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 - in: query name: perPage description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 required: false schema: type: integer description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 - in: query name: sort description: 'Must not be greater than 255 characters.' example: adavrgpuborfidxrixzylsn required: false schema: type: string description: 'Must not be greater than 255 characters.' example: adavrgpuborfidxrixzylsn - in: query name: sortBy description: 'Must not be greater than 255 characters.' example: tvgfntshceojlo required: false schema: type: string description: 'Must not be greater than 255 characters.' example: tvgfntshceojlo - in: query name: sortOrder description: '' example: desc required: false schema: type: string description: '' example: desc enum: - asc - desc - in: query name: filter description: '' example: null required: false schema: type: object description: '' example: null properties: { } - in: query name: filter.search description: 'Must not be greater than 255 characters.' example: bwuglqcb required: false schema: type: string description: 'Must not be greater than 255 characters.' example: bwuglqcb - in: query name: filter.active description: '' example: false required: false schema: type: boolean description: '' example: false - in: query name: filter.enabled description: '' example: true required: false schema: type: boolean description: '' example: true responses: 200: description: '' content: application/json: schema: type: object example: data: [] links: first: 'https://tracklabsolar.com/api/v1/type/company-link-status?page=1' last: 'https://tracklabsolar.com/api/v1/type/company-link-status?page=1' prev: null next: null meta: current_page: 1 from: null last_page: 1 links: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/company-link-status?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false path: 'https://tracklabsolar.com/api/v1/type/company-link-status' per_page: 20 to: null total: 0 properties: data: type: array example: [] links: type: object properties: first: type: string example: 'https://tracklabsolar.com/api/v1/type/company-link-status?page=1' last: type: string example: 'https://tracklabsolar.com/api/v1/type/company-link-status?page=1' prev: type: string example: null nullable: true next: type: string example: null nullable: true meta: type: object properties: current_page: type: integer example: 1 from: type: string example: null nullable: true last_page: type: integer example: 1 links: type: array example: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/company-link-status?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false items: type: object properties: url: type: string example: null nullable: true label: type: string example: '« Previous' page: type: string example: null nullable: true active: type: boolean example: false path: type: string example: 'https://tracklabsolar.com/api/v1/type/company-link-status' per_page: type: integer example: 20 to: type: string example: null nullable: true total: type: integer example: 0 tags: - Endpoints /api/v1/type/data-deletion-audit-status: get: summary: '' operationId: getApiV1TypeDataDeletionAuditStatus description: '' parameters: - in: query name: page description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 required: false schema: type: integer description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 - in: query name: perPage description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 required: false schema: type: integer description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 - in: query name: sort description: 'Must not be greater than 255 characters.' example: ckqdjvi required: false schema: type: string description: 'Must not be greater than 255 characters.' example: ckqdjvi - in: query name: sortBy description: 'Must not be greater than 255 characters.' example: dle required: false schema: type: string description: 'Must not be greater than 255 characters.' example: dle - in: query name: sortOrder description: '' example: asc required: false schema: type: string description: '' example: asc enum: - asc - desc - in: query name: filter description: '' example: null required: false schema: type: object description: '' example: null properties: { } - in: query name: filter.search description: 'Must not be greater than 255 characters.' example: sllmjnedhhkipnpmq required: false schema: type: string description: 'Must not be greater than 255 characters.' example: sllmjnedhhkipnpmq - in: query name: filter.active description: '' example: true required: false schema: type: boolean description: '' example: true - in: query name: filter.enabled description: '' example: false required: false schema: type: boolean description: '' example: false responses: 200: description: '' content: application/json: schema: type: object example: data: [] links: first: 'https://tracklabsolar.com/api/v1/type/data-deletion-audit-status?page=1' last: 'https://tracklabsolar.com/api/v1/type/data-deletion-audit-status?page=1' prev: null next: null meta: current_page: 1 from: null last_page: 1 links: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/data-deletion-audit-status?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false path: 'https://tracklabsolar.com/api/v1/type/data-deletion-audit-status' per_page: 20 to: null total: 0 properties: data: type: array example: [] links: type: object properties: first: type: string example: 'https://tracklabsolar.com/api/v1/type/data-deletion-audit-status?page=1' last: type: string example: 'https://tracklabsolar.com/api/v1/type/data-deletion-audit-status?page=1' prev: type: string example: null nullable: true next: type: string example: null nullable: true meta: type: object properties: current_page: type: integer example: 1 from: type: string example: null nullable: true last_page: type: integer example: 1 links: type: array example: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/data-deletion-audit-status?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false items: type: object properties: url: type: string example: null nullable: true label: type: string example: '« Previous' page: type: string example: null nullable: true active: type: boolean example: false path: type: string example: 'https://tracklabsolar.com/api/v1/type/data-deletion-audit-status' per_page: type: integer example: 20 to: type: string example: null nullable: true total: type: integer example: 0 tags: - Endpoints /api/v1/type/data-retention-data: get: summary: '' operationId: getApiV1TypeDataRetentionData description: '' parameters: - in: query name: page description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 required: false schema: type: integer description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 - in: query name: perPage description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 required: false schema: type: integer description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 - in: query name: sort description: 'Must not be greater than 255 characters.' example: mjhitiz required: false schema: type: string description: 'Must not be greater than 255 characters.' example: mjhitiz - in: query name: sortBy description: 'Must not be greater than 255 characters.' example: lfyq required: false schema: type: string description: 'Must not be greater than 255 characters.' example: lfyq - in: query name: sortOrder description: '' example: asc required: false schema: type: string description: '' example: asc enum: - asc - desc - in: query name: filter description: '' example: null required: false schema: type: object description: '' example: null properties: { } - in: query name: filter.search description: 'Must not be greater than 255 characters.' example: d required: false schema: type: string description: 'Must not be greater than 255 characters.' example: d - in: query name: filter.active description: '' example: true required: false schema: type: boolean description: '' example: true - in: query name: filter.enabled description: '' example: true required: false schema: type: boolean description: '' example: true responses: 200: description: '' content: application/json: schema: type: object example: data: - slug: device-messages name: 'Device Messages' description: '' - slug: device-commands name: 'Device Commands' description: '' - slug: automation-events name: 'Automation Events' description: 'Automation events and their context data' - slug: automation-executions name: 'Automation Executions' description: 'Automation action executions and notification dispatches' links: first: 'https://tracklabsolar.com/api/v1/type/data-retention-data?page=1' last: 'https://tracklabsolar.com/api/v1/type/data-retention-data?page=1' prev: null next: null meta: current_page: 1 from: 1 last_page: 1 links: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/data-retention-data?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false path: 'https://tracklabsolar.com/api/v1/type/data-retention-data' per_page: 20 to: 4 total: 4 properties: data: type: array example: - slug: device-messages name: 'Device Messages' description: '' - slug: device-commands name: 'Device Commands' description: '' - slug: automation-events name: 'Automation Events' description: 'Automation events and their context data' - slug: automation-executions name: 'Automation Executions' description: 'Automation action executions and notification dispatches' items: type: object properties: slug: type: string example: device-messages name: type: string example: 'Device Messages' description: type: string example: '' links: type: object properties: first: type: string example: 'https://tracklabsolar.com/api/v1/type/data-retention-data?page=1' last: type: string example: 'https://tracklabsolar.com/api/v1/type/data-retention-data?page=1' prev: type: string example: null nullable: true next: type: string example: null nullable: true meta: type: object properties: current_page: type: integer example: 1 from: type: integer example: 1 last_page: type: integer example: 1 links: type: array example: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/data-retention-data?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false items: type: object properties: url: type: string example: null nullable: true label: type: string example: '« Previous' page: type: string example: null nullable: true active: type: boolean example: false path: type: string example: 'https://tracklabsolar.com/api/v1/type/data-retention-data' per_page: type: integer example: 20 to: type: integer example: 4 total: type: integer example: 4 tags: - Endpoints /api/v1/type/device-message-processing-status: get: summary: '' operationId: getApiV1TypeDeviceMessageProcessingStatus description: '' parameters: - in: query name: page description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 required: false schema: type: integer description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 - in: query name: perPage description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 required: false schema: type: integer description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 - in: query name: sort description: 'Must not be greater than 255 characters.' example: ypcdgmasypbrtrnthcppaqgcg required: false schema: type: string description: 'Must not be greater than 255 characters.' example: ypcdgmasypbrtrnthcppaqgcg - in: query name: sortBy description: 'Must not be greater than 255 characters.' example: jsyrgfxpcumarqxua required: false schema: type: string description: 'Must not be greater than 255 characters.' example: jsyrgfxpcumarqxua - in: query name: sortOrder description: '' example: desc required: false schema: type: string description: '' example: desc enum: - asc - desc - in: query name: filter description: '' example: null required: false schema: type: object description: '' example: null properties: { } - in: query name: filter.search description: 'Must not be greater than 255 characters.' example: tuyotle required: false schema: type: string description: 'Must not be greater than 255 characters.' example: tuyotle - in: query name: filter.active description: '' example: false required: false schema: type: boolean description: '' example: false - in: query name: filter.enabled description: '' example: false required: false schema: type: boolean description: '' example: false responses: 200: description: '' content: application/json: schema: type: object example: data: [] links: first: 'https://tracklabsolar.com/api/v1/type/device-message-processing-status?page=1' last: 'https://tracklabsolar.com/api/v1/type/device-message-processing-status?page=1' prev: null next: null meta: current_page: 1 from: null last_page: 1 links: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/device-message-processing-status?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false path: 'https://tracklabsolar.com/api/v1/type/device-message-processing-status' per_page: 20 to: null total: 0 properties: data: type: array example: [] links: type: object properties: first: type: string example: 'https://tracklabsolar.com/api/v1/type/device-message-processing-status?page=1' last: type: string example: 'https://tracklabsolar.com/api/v1/type/device-message-processing-status?page=1' prev: type: string example: null nullable: true next: type: string example: null nullable: true meta: type: object properties: current_page: type: integer example: 1 from: type: string example: null nullable: true last_page: type: integer example: 1 links: type: array example: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/device-message-processing-status?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false items: type: object properties: url: type: string example: null nullable: true label: type: string example: '« Previous' page: type: string example: null nullable: true active: type: boolean example: false path: type: string example: 'https://tracklabsolar.com/api/v1/type/device-message-processing-status' per_page: type: integer example: 20 to: type: string example: null nullable: true total: type: integer example: 0 tags: - Endpoints /api/v1/type/failure: get: summary: '' operationId: getApiV1TypeFailure description: '' parameters: - in: query name: page description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 required: false schema: type: integer description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 - in: query name: perPage description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 required: false schema: type: integer description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 - in: query name: sort description: 'Must not be greater than 255 characters.' example: anfizvbk required: false schema: type: string description: 'Must not be greater than 255 characters.' example: anfizvbk - in: query name: sortBy description: 'Must not be greater than 255 characters.' example: tfkvhrjitqfeyyuxqztmrhn required: false schema: type: string description: 'Must not be greater than 255 characters.' example: tfkvhrjitqfeyyuxqztmrhn - in: query name: sortOrder description: '' example: asc required: false schema: type: string description: '' example: asc enum: - asc - desc - in: query name: filter description: '' example: null required: false schema: type: object description: '' example: null properties: { } - in: query name: filter.search description: 'Must not be greater than 255 characters.' example: rcj required: false schema: type: string description: 'Must not be greater than 255 characters.' example: rcj - in: query name: filter.active description: '' example: true required: false schema: type: boolean description: '' example: true - in: query name: filter.enabled description: '' example: false required: false schema: type: boolean description: '' example: false responses: 200: description: '' content: application/json: schema: type: object example: data: [] links: first: 'https://tracklabsolar.com/api/v1/type/failure?page=1' last: 'https://tracklabsolar.com/api/v1/type/failure?page=1' prev: null next: null meta: current_page: 1 from: null last_page: 1 links: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/failure?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false path: 'https://tracklabsolar.com/api/v1/type/failure' per_page: 20 to: null total: 0 properties: data: type: array example: [] links: type: object properties: first: type: string example: 'https://tracklabsolar.com/api/v1/type/failure?page=1' last: type: string example: 'https://tracklabsolar.com/api/v1/type/failure?page=1' prev: type: string example: null nullable: true next: type: string example: null nullable: true meta: type: object properties: current_page: type: integer example: 1 from: type: string example: null nullable: true last_page: type: integer example: 1 links: type: array example: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/failure?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false items: type: object properties: url: type: string example: null nullable: true label: type: string example: '« Previous' page: type: string example: null nullable: true active: type: boolean example: false path: type: string example: 'https://tracklabsolar.com/api/v1/type/failure' per_page: type: integer example: 20 to: type: string example: null nullable: true total: type: integer example: 0 tags: - Endpoints /api/v1/type/invitation-status: get: summary: '' operationId: getApiV1TypeInvitationStatus description: '' parameters: - in: query name: page description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 required: false schema: type: integer description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 - in: query name: perPage description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 required: false schema: type: integer description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 - in: query name: sort description: 'Must not be greater than 255 characters.' example: nxhxdarhqarjqesn required: false schema: type: string description: 'Must not be greater than 255 characters.' example: nxhxdarhqarjqesn - in: query name: sortBy description: 'Must not be greater than 255 characters.' example: srkty required: false schema: type: string description: 'Must not be greater than 255 characters.' example: srkty - in: query name: sortOrder description: '' example: asc required: false schema: type: string description: '' example: asc enum: - asc - desc - in: query name: filter description: '' example: null required: false schema: type: object description: '' example: null properties: { } - in: query name: filter.search description: 'Must not be greater than 255 characters.' example: hcuhglkbenpidbcxfuqgkverl required: false schema: type: string description: 'Must not be greater than 255 characters.' example: hcuhglkbenpidbcxfuqgkverl - in: query name: filter.active description: '' example: false required: false schema: type: boolean description: '' example: false - in: query name: filter.enabled description: '' example: false required: false schema: type: boolean description: '' example: false responses: 200: description: '' content: application/json: schema: type: object example: data: [] links: first: 'https://tracklabsolar.com/api/v1/type/invitation-status?page=1' last: 'https://tracklabsolar.com/api/v1/type/invitation-status?page=1' prev: null next: null meta: current_page: 1 from: null last_page: 1 links: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/invitation-status?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false path: 'https://tracklabsolar.com/api/v1/type/invitation-status' per_page: 20 to: null total: 0 properties: data: type: array example: [] links: type: object properties: first: type: string example: 'https://tracklabsolar.com/api/v1/type/invitation-status?page=1' last: type: string example: 'https://tracklabsolar.com/api/v1/type/invitation-status?page=1' prev: type: string example: null nullable: true next: type: string example: null nullable: true meta: type: object properties: current_page: type: integer example: 1 from: type: string example: null nullable: true last_page: type: integer example: 1 links: type: array example: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/invitation-status?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false items: type: object properties: url: type: string example: null nullable: true label: type: string example: '« Previous' page: type: string example: null nullable: true active: type: boolean example: false path: type: string example: 'https://tracklabsolar.com/api/v1/type/invitation-status' per_page: type: integer example: 20 to: type: string example: null nullable: true total: type: integer example: 0 tags: - Endpoints /api/v1/type/ip: get: summary: '' operationId: getApiV1TypeIp description: '' parameters: - in: query name: page description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 required: false schema: type: integer description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 - in: query name: perPage description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 required: false schema: type: integer description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 - in: query name: sort description: 'Must not be greater than 255 characters.' example: drdfougftpbxegzhhnpcnk required: false schema: type: string description: 'Must not be greater than 255 characters.' example: drdfougftpbxegzhhnpcnk - in: query name: sortBy description: 'Must not be greater than 255 characters.' example: oazdlburhctwnl required: false schema: type: string description: 'Must not be greater than 255 characters.' example: oazdlburhctwnl - in: query name: sortOrder description: '' example: asc required: false schema: type: string description: '' example: asc enum: - asc - desc - in: query name: filter description: '' example: null required: false schema: type: object description: '' example: null properties: { } - in: query name: filter.search description: 'Must not be greater than 255 characters.' example: ufzwlwhafgfiydt required: false schema: type: string description: 'Must not be greater than 255 characters.' example: ufzwlwhafgfiydt - in: query name: filter.active description: '' example: false required: false schema: type: boolean description: '' example: false - in: query name: filter.enabled description: '' example: true required: false schema: type: boolean description: '' example: true responses: 200: description: '' content: application/json: schema: type: object example: data: [] links: first: 'https://tracklabsolar.com/api/v1/type/ip?page=1' last: 'https://tracklabsolar.com/api/v1/type/ip?page=1' prev: null next: null meta: current_page: 1 from: null last_page: 1 links: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/ip?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false path: 'https://tracklabsolar.com/api/v1/type/ip' per_page: 20 to: null total: 0 properties: data: type: array example: [] links: type: object properties: first: type: string example: 'https://tracklabsolar.com/api/v1/type/ip?page=1' last: type: string example: 'https://tracklabsolar.com/api/v1/type/ip?page=1' prev: type: string example: null nullable: true next: type: string example: null nullable: true meta: type: object properties: current_page: type: integer example: 1 from: type: string example: null nullable: true last_page: type: integer example: 1 links: type: array example: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/ip?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false items: type: object properties: url: type: string example: null nullable: true label: type: string example: '« Previous' page: type: string example: null nullable: true active: type: boolean example: false path: type: string example: 'https://tracklabsolar.com/api/v1/type/ip' per_page: type: integer example: 20 to: type: string example: null nullable: true total: type: integer example: 0 tags: - Endpoints /api/v1/type/mime-type-list: get: summary: '' operationId: getApiV1TypeMimeTypeList description: '' parameters: - in: query name: page description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 required: false schema: type: integer description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 - in: query name: perPage description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 required: false schema: type: integer description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 - in: query name: sort description: 'Must not be greater than 255 characters.' example: lueq required: false schema: type: string description: 'Must not be greater than 255 characters.' example: lueq - in: query name: sortBy description: 'Must not be greater than 255 characters.' example: dqgy required: false schema: type: string description: 'Must not be greater than 255 characters.' example: dqgy - in: query name: sortOrder description: '' example: desc required: false schema: type: string description: '' example: desc enum: - asc - desc - in: query name: filter description: '' example: null required: false schema: type: object description: '' example: null properties: { } - in: query name: filter.search description: 'Must not be greater than 255 characters.' example: xfqqfusnfjcqlxktxyd required: false schema: type: string description: 'Must not be greater than 255 characters.' example: xfqqfusnfjcqlxktxyd - in: query name: filter.active description: '' example: true required: false schema: type: boolean description: '' example: true - in: query name: filter.enabled description: '' example: true required: false schema: type: boolean description: '' example: true responses: 200: description: '' content: application/json: schema: type: object example: data: [] links: first: 'https://tracklabsolar.com/api/v1/type/mime-type-list?page=1' last: 'https://tracklabsolar.com/api/v1/type/mime-type-list?page=1' prev: null next: null meta: current_page: 1 from: null last_page: 1 links: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/mime-type-list?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false path: 'https://tracklabsolar.com/api/v1/type/mime-type-list' per_page: 20 to: null total: 0 properties: data: type: array example: [] links: type: object properties: first: type: string example: 'https://tracklabsolar.com/api/v1/type/mime-type-list?page=1' last: type: string example: 'https://tracklabsolar.com/api/v1/type/mime-type-list?page=1' prev: type: string example: null nullable: true next: type: string example: null nullable: true meta: type: object properties: current_page: type: integer example: 1 from: type: string example: null nullable: true last_page: type: integer example: 1 links: type: array example: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/mime-type-list?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false items: type: object properties: url: type: string example: null nullable: true label: type: string example: '« Previous' page: type: string example: null nullable: true active: type: boolean example: false path: type: string example: 'https://tracklabsolar.com/api/v1/type/mime-type-list' per_page: type: integer example: 20 to: type: string example: null nullable: true total: type: integer example: 0 tags: - Endpoints /api/v1/type/mobile-app-version: get: summary: '' operationId: getApiV1TypeMobileAppVersion description: '' parameters: - in: query name: page description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 required: false schema: type: integer description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 - in: query name: perPage description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 required: false schema: type: integer description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 - in: query name: sort description: 'Must not be greater than 255 characters.' example: iefqudev required: false schema: type: string description: 'Must not be greater than 255 characters.' example: iefqudev - in: query name: sortBy description: 'Must not be greater than 255 characters.' example: quzug required: false schema: type: string description: 'Must not be greater than 255 characters.' example: quzug - in: query name: sortOrder description: '' example: asc required: false schema: type: string description: '' example: asc enum: - asc - desc - in: query name: filter description: '' example: null required: false schema: type: object description: '' example: null properties: { } - in: query name: filter.search description: 'Must not be greater than 255 characters.' example: u required: false schema: type: string description: 'Must not be greater than 255 characters.' example: u - in: query name: filter.active description: '' example: false required: false schema: type: boolean description: '' example: false - in: query name: filter.enabled description: '' example: false required: false schema: type: boolean description: '' example: false responses: 200: description: '' content: application/json: schema: type: object example: data: [] links: first: 'https://tracklabsolar.com/api/v1/type/mobile-app-version?page=1' last: 'https://tracklabsolar.com/api/v1/type/mobile-app-version?page=1' prev: null next: null meta: current_page: 1 from: null last_page: 1 links: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/mobile-app-version?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false path: 'https://tracklabsolar.com/api/v1/type/mobile-app-version' per_page: 20 to: null total: 0 properties: data: type: array example: [] links: type: object properties: first: type: string example: 'https://tracklabsolar.com/api/v1/type/mobile-app-version?page=1' last: type: string example: 'https://tracklabsolar.com/api/v1/type/mobile-app-version?page=1' prev: type: string example: null nullable: true next: type: string example: null nullable: true meta: type: object properties: current_page: type: integer example: 1 from: type: string example: null nullable: true last_page: type: integer example: 1 links: type: array example: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/mobile-app-version?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false items: type: object properties: url: type: string example: null nullable: true label: type: string example: '« Previous' page: type: string example: null nullable: true active: type: boolean example: false path: type: string example: 'https://tracklabsolar.com/api/v1/type/mobile-app-version' per_page: type: integer example: 20 to: type: string example: null nullable: true total: type: integer example: 0 tags: - Endpoints /api/v1/type/mobile-audit-action: get: summary: '' operationId: getApiV1TypeMobileAuditAction description: '' parameters: - in: query name: page description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 required: false schema: type: integer description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 - in: query name: perPage description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 required: false schema: type: integer description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 - in: query name: sort description: 'Must not be greater than 255 characters.' example: jdbpifinqzjksapv required: false schema: type: string description: 'Must not be greater than 255 characters.' example: jdbpifinqzjksapv - in: query name: sortBy description: 'Must not be greater than 255 characters.' example: zchjerznmyzijiabckbnzs required: false schema: type: string description: 'Must not be greater than 255 characters.' example: zchjerznmyzijiabckbnzs - in: query name: sortOrder description: '' example: asc required: false schema: type: string description: '' example: asc enum: - asc - desc - in: query name: filter description: '' example: null required: false schema: type: object description: '' example: null properties: { } - in: query name: filter.search description: 'Must not be greater than 255 characters.' example: yunrirsv required: false schema: type: string description: 'Must not be greater than 255 characters.' example: yunrirsv - in: query name: filter.active description: '' example: true required: false schema: type: boolean description: '' example: true - in: query name: filter.enabled description: '' example: true required: false schema: type: boolean description: '' example: true responses: 200: description: '' content: application/json: schema: type: object example: data: [] links: first: 'https://tracklabsolar.com/api/v1/type/mobile-audit-action?page=1' last: 'https://tracklabsolar.com/api/v1/type/mobile-audit-action?page=1' prev: null next: null meta: current_page: 1 from: null last_page: 1 links: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/mobile-audit-action?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false path: 'https://tracklabsolar.com/api/v1/type/mobile-audit-action' per_page: 20 to: null total: 0 properties: data: type: array example: [] links: type: object properties: first: type: string example: 'https://tracklabsolar.com/api/v1/type/mobile-audit-action?page=1' last: type: string example: 'https://tracklabsolar.com/api/v1/type/mobile-audit-action?page=1' prev: type: string example: null nullable: true next: type: string example: null nullable: true meta: type: object properties: current_page: type: integer example: 1 from: type: string example: null nullable: true last_page: type: integer example: 1 links: type: array example: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/mobile-audit-action?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false items: type: object properties: url: type: string example: null nullable: true label: type: string example: '« Previous' page: type: string example: null nullable: true active: type: boolean example: false path: type: string example: 'https://tracklabsolar.com/api/v1/type/mobile-audit-action' per_page: type: integer example: 20 to: type: string example: null nullable: true total: type: integer example: 0 tags: - Endpoints /api/v1/type/mobile-audit-connection: get: summary: '' operationId: getApiV1TypeMobileAuditConnection description: '' parameters: - in: query name: page description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 required: false schema: type: integer description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 - in: query name: perPage description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 required: false schema: type: integer description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 - in: query name: sort description: 'Must not be greater than 255 characters.' example: qqmkygtwfjllvfxszwkfgfywc required: false schema: type: string description: 'Must not be greater than 255 characters.' example: qqmkygtwfjllvfxszwkfgfywc - in: query name: sortBy description: 'Must not be greater than 255 characters.' example: ohkwtmxksfseuyakdtfq required: false schema: type: string description: 'Must not be greater than 255 characters.' example: ohkwtmxksfseuyakdtfq - in: query name: sortOrder description: '' example: desc required: false schema: type: string description: '' example: desc enum: - asc - desc - in: query name: filter description: '' example: null required: false schema: type: object description: '' example: null properties: { } - in: query name: filter.search description: 'Must not be greater than 255 characters.' example: ajxsopdpncn required: false schema: type: string description: 'Must not be greater than 255 characters.' example: ajxsopdpncn - in: query name: filter.active description: '' example: true required: false schema: type: boolean description: '' example: true - in: query name: filter.enabled description: '' example: true required: false schema: type: boolean description: '' example: true responses: 200: description: '' content: application/json: schema: type: object example: data: [] links: first: 'https://tracklabsolar.com/api/v1/type/mobile-audit-connection?page=1' last: 'https://tracklabsolar.com/api/v1/type/mobile-audit-connection?page=1' prev: null next: null meta: current_page: 1 from: null last_page: 1 links: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/mobile-audit-connection?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false path: 'https://tracklabsolar.com/api/v1/type/mobile-audit-connection' per_page: 20 to: null total: 0 properties: data: type: array example: [] links: type: object properties: first: type: string example: 'https://tracklabsolar.com/api/v1/type/mobile-audit-connection?page=1' last: type: string example: 'https://tracklabsolar.com/api/v1/type/mobile-audit-connection?page=1' prev: type: string example: null nullable: true next: type: string example: null nullable: true meta: type: object properties: current_page: type: integer example: 1 from: type: string example: null nullable: true last_page: type: integer example: 1 links: type: array example: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/mobile-audit-connection?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false items: type: object properties: url: type: string example: null nullable: true label: type: string example: '« Previous' page: type: string example: null nullable: true active: type: boolean example: false path: type: string example: 'https://tracklabsolar.com/api/v1/type/mobile-audit-connection' per_page: type: integer example: 20 to: type: string example: null nullable: true total: type: integer example: 0 tags: - Endpoints /api/v1/type/mobile-audit-event: get: summary: '' operationId: getApiV1TypeMobileAuditEvent description: '' parameters: - in: query name: page description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 required: false schema: type: integer description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 - in: query name: perPage description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 required: false schema: type: integer description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 - in: query name: sort description: 'Must not be greater than 255 characters.' example: mhtmansoeywsddpkqwt required: false schema: type: string description: 'Must not be greater than 255 characters.' example: mhtmansoeywsddpkqwt - in: query name: sortBy description: 'Must not be greater than 255 characters.' example: zkukjuedavmzftitwyxf required: false schema: type: string description: 'Must not be greater than 255 characters.' example: zkukjuedavmzftitwyxf - in: query name: sortOrder description: '' example: asc required: false schema: type: string description: '' example: asc enum: - asc - desc - in: query name: filter description: '' example: null required: false schema: type: object description: '' example: null properties: { } - in: query name: filter.search description: 'Must not be greater than 255 characters.' example: usmikohumbodtuqbxub required: false schema: type: string description: 'Must not be greater than 255 characters.' example: usmikohumbodtuqbxub - in: query name: filter.active description: '' example: false required: false schema: type: boolean description: '' example: false - in: query name: filter.enabled description: '' example: true required: false schema: type: boolean description: '' example: true responses: 200: description: '' content: application/json: schema: type: object example: data: [] links: first: 'https://tracklabsolar.com/api/v1/type/mobile-audit-event?page=1' last: 'https://tracklabsolar.com/api/v1/type/mobile-audit-event?page=1' prev: null next: null meta: current_page: 1 from: null last_page: 1 links: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/mobile-audit-event?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false path: 'https://tracklabsolar.com/api/v1/type/mobile-audit-event' per_page: 20 to: null total: 0 properties: data: type: array example: [] links: type: object properties: first: type: string example: 'https://tracklabsolar.com/api/v1/type/mobile-audit-event?page=1' last: type: string example: 'https://tracklabsolar.com/api/v1/type/mobile-audit-event?page=1' prev: type: string example: null nullable: true next: type: string example: null nullable: true meta: type: object properties: current_page: type: integer example: 1 from: type: string example: null nullable: true last_page: type: integer example: 1 links: type: array example: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/mobile-audit-event?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false items: type: object properties: url: type: string example: null nullable: true label: type: string example: '« Previous' page: type: string example: null nullable: true active: type: boolean example: false path: type: string example: 'https://tracklabsolar.com/api/v1/type/mobile-audit-event' per_page: type: integer example: 20 to: type: string example: null nullable: true total: type: integer example: 0 tags: - Endpoints /api/v1/type/mobile-audit-result-status: get: summary: '' operationId: getApiV1TypeMobileAuditResultStatus description: '' parameters: - in: query name: page description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 required: false schema: type: integer description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 - in: query name: perPage description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 required: false schema: type: integer description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 - in: query name: sort description: 'Must not be greater than 255 characters.' example: c required: false schema: type: string description: 'Must not be greater than 255 characters.' example: c - in: query name: sortBy description: 'Must not be greater than 255 characters.' example: owfidxsnqua required: false schema: type: string description: 'Must not be greater than 255 characters.' example: owfidxsnqua - in: query name: sortOrder description: '' example: asc required: false schema: type: string description: '' example: asc enum: - asc - desc - in: query name: filter description: '' example: null required: false schema: type: object description: '' example: null properties: { } - in: query name: filter.search description: 'Must not be greater than 255 characters.' example: uqygneebtrxehlfgaj required: false schema: type: string description: 'Must not be greater than 255 characters.' example: uqygneebtrxehlfgaj - in: query name: filter.active description: '' example: true required: false schema: type: boolean description: '' example: true - in: query name: filter.enabled description: '' example: false required: false schema: type: boolean description: '' example: false responses: 200: description: '' content: application/json: schema: type: object example: data: [] links: first: 'https://tracklabsolar.com/api/v1/type/mobile-audit-result-status?page=1' last: 'https://tracklabsolar.com/api/v1/type/mobile-audit-result-status?page=1' prev: null next: null meta: current_page: 1 from: null last_page: 1 links: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/mobile-audit-result-status?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false path: 'https://tracklabsolar.com/api/v1/type/mobile-audit-result-status' per_page: 20 to: null total: 0 properties: data: type: array example: [] links: type: object properties: first: type: string example: 'https://tracklabsolar.com/api/v1/type/mobile-audit-result-status?page=1' last: type: string example: 'https://tracklabsolar.com/api/v1/type/mobile-audit-result-status?page=1' prev: type: string example: null nullable: true next: type: string example: null nullable: true meta: type: object properties: current_page: type: integer example: 1 from: type: string example: null nullable: true last_page: type: integer example: 1 links: type: array example: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/mobile-audit-result-status?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false items: type: object properties: url: type: string example: null nullable: true label: type: string example: '« Previous' page: type: string example: null nullable: true active: type: boolean example: false path: type: string example: 'https://tracklabsolar.com/api/v1/type/mobile-audit-result-status' per_page: type: integer example: 20 to: type: string example: null nullable: true total: type: integer example: 0 tags: - Endpoints /api/v1/type/mobile-build-number: get: summary: '' operationId: getApiV1TypeMobileBuildNumber description: '' parameters: - in: query name: page description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 required: false schema: type: integer description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 - in: query name: perPage description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 required: false schema: type: integer description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 - in: query name: sort description: 'Must not be greater than 255 characters.' example: umqxnk required: false schema: type: string description: 'Must not be greater than 255 characters.' example: umqxnk - in: query name: sortBy description: 'Must not be greater than 255 characters.' example: wj required: false schema: type: string description: 'Must not be greater than 255 characters.' example: wj - in: query name: sortOrder description: '' example: asc required: false schema: type: string description: '' example: asc enum: - asc - desc - in: query name: filter description: '' example: null required: false schema: type: object description: '' example: null properties: { } - in: query name: filter.search description: 'Must not be greater than 255 characters.' example: lbfwlnfqjc required: false schema: type: string description: 'Must not be greater than 255 characters.' example: lbfwlnfqjc - in: query name: filter.active description: '' example: false required: false schema: type: boolean description: '' example: false - in: query name: filter.enabled description: '' example: true required: false schema: type: boolean description: '' example: true responses: 200: description: '' content: application/json: schema: type: object example: data: [] links: first: 'https://tracklabsolar.com/api/v1/type/mobile-build-number?page=1' last: 'https://tracklabsolar.com/api/v1/type/mobile-build-number?page=1' prev: null next: null meta: current_page: 1 from: null last_page: 1 links: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/mobile-build-number?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false path: 'https://tracklabsolar.com/api/v1/type/mobile-build-number' per_page: 20 to: null total: 0 properties: data: type: array example: [] links: type: object properties: first: type: string example: 'https://tracklabsolar.com/api/v1/type/mobile-build-number?page=1' last: type: string example: 'https://tracklabsolar.com/api/v1/type/mobile-build-number?page=1' prev: type: string example: null nullable: true next: type: string example: null nullable: true meta: type: object properties: current_page: type: integer example: 1 from: type: string example: null nullable: true last_page: type: integer example: 1 links: type: array example: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/mobile-build-number?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false items: type: object properties: url: type: string example: null nullable: true label: type: string example: '« Previous' page: type: string example: null nullable: true active: type: boolean example: false path: type: string example: 'https://tracklabsolar.com/api/v1/type/mobile-build-number' per_page: type: integer example: 20 to: type: string example: null nullable: true total: type: integer example: 0 tags: - Endpoints /api/v1/type/mobile-device-model: get: summary: '' operationId: getApiV1TypeMobileDeviceModel description: '' parameters: - in: query name: page description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 required: false schema: type: integer description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 - in: query name: perPage description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 required: false schema: type: integer description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 - in: query name: sort description: 'Must not be greater than 255 characters.' example: xalzyiolvgggkysepuzcer required: false schema: type: string description: 'Must not be greater than 255 characters.' example: xalzyiolvgggkysepuzcer - in: query name: sortBy description: 'Must not be greater than 255 characters.' example: rxnyduiqwpkvthstjqjcmp required: false schema: type: string description: 'Must not be greater than 255 characters.' example: rxnyduiqwpkvthstjqjcmp - in: query name: sortOrder description: '' example: asc required: false schema: type: string description: '' example: asc enum: - asc - desc - in: query name: filter description: '' example: null required: false schema: type: object description: '' example: null properties: { } - in: query name: filter.search description: 'Must not be greater than 255 characters.' example: w required: false schema: type: string description: 'Must not be greater than 255 characters.' example: w - in: query name: filter.active description: '' example: false required: false schema: type: boolean description: '' example: false - in: query name: filter.enabled description: '' example: true required: false schema: type: boolean description: '' example: true responses: 200: description: '' content: application/json: schema: type: object example: data: [] links: first: 'https://tracklabsolar.com/api/v1/type/mobile-device-model?page=1' last: 'https://tracklabsolar.com/api/v1/type/mobile-device-model?page=1' prev: null next: null meta: current_page: 1 from: null last_page: 1 links: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/mobile-device-model?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false path: 'https://tracklabsolar.com/api/v1/type/mobile-device-model' per_page: 20 to: null total: 0 properties: data: type: array example: [] links: type: object properties: first: type: string example: 'https://tracklabsolar.com/api/v1/type/mobile-device-model?page=1' last: type: string example: 'https://tracklabsolar.com/api/v1/type/mobile-device-model?page=1' prev: type: string example: null nullable: true next: type: string example: null nullable: true meta: type: object properties: current_page: type: integer example: 1 from: type: string example: null nullable: true last_page: type: integer example: 1 links: type: array example: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/mobile-device-model?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false items: type: object properties: url: type: string example: null nullable: true label: type: string example: '« Previous' page: type: string example: null nullable: true active: type: boolean example: false path: type: string example: 'https://tracklabsolar.com/api/v1/type/mobile-device-model' per_page: type: integer example: 20 to: type: string example: null nullable: true total: type: integer example: 0 tags: - Endpoints /api/v1/type/mobile-operator-label: get: summary: '' operationId: getApiV1TypeMobileOperatorLabel description: '' parameters: - in: query name: page description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 required: false schema: type: integer description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 - in: query name: perPage description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 required: false schema: type: integer description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 - in: query name: sort description: 'Must not be greater than 255 characters.' example: ufyauvjkfgbfsfvcvhwqem required: false schema: type: string description: 'Must not be greater than 255 characters.' example: ufyauvjkfgbfsfvcvhwqem - in: query name: sortBy description: 'Must not be greater than 255 characters.' example: tlgk required: false schema: type: string description: 'Must not be greater than 255 characters.' example: tlgk - in: query name: sortOrder description: '' example: asc required: false schema: type: string description: '' example: asc enum: - asc - desc - in: query name: filter description: '' example: null required: false schema: type: object description: '' example: null properties: { } - in: query name: filter.search description: 'Must not be greater than 255 characters.' example: ycpdbifvpjhkgijtz required: false schema: type: string description: 'Must not be greater than 255 characters.' example: ycpdbifvpjhkgijtz - in: query name: filter.active description: '' example: false required: false schema: type: boolean description: '' example: false - in: query name: filter.enabled description: '' example: false required: false schema: type: boolean description: '' example: false responses: 200: description: '' content: application/json: schema: type: object example: data: [] links: first: 'https://tracklabsolar.com/api/v1/type/mobile-operator-label?page=1' last: 'https://tracklabsolar.com/api/v1/type/mobile-operator-label?page=1' prev: null next: null meta: current_page: 1 from: null last_page: 1 links: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/mobile-operator-label?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false path: 'https://tracklabsolar.com/api/v1/type/mobile-operator-label' per_page: 20 to: null total: 0 properties: data: type: array example: [] links: type: object properties: first: type: string example: 'https://tracklabsolar.com/api/v1/type/mobile-operator-label?page=1' last: type: string example: 'https://tracklabsolar.com/api/v1/type/mobile-operator-label?page=1' prev: type: string example: null nullable: true next: type: string example: null nullable: true meta: type: object properties: current_page: type: integer example: 1 from: type: string example: null nullable: true last_page: type: integer example: 1 links: type: array example: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/mobile-operator-label?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false items: type: object properties: url: type: string example: null nullable: true label: type: string example: '« Previous' page: type: string example: null nullable: true active: type: boolean example: false path: type: string example: 'https://tracklabsolar.com/api/v1/type/mobile-operator-label' per_page: type: integer example: 20 to: type: string example: null nullable: true total: type: integer example: 0 tags: - Endpoints /api/v1/type/mobile-os-version: get: summary: '' operationId: getApiV1TypeMobileOsVersion description: '' parameters: - in: query name: page description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 required: false schema: type: integer description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 - in: query name: perPage description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 required: false schema: type: integer description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 - in: query name: sort description: 'Must not be greater than 255 characters.' example: cfjspkytaurk required: false schema: type: string description: 'Must not be greater than 255 characters.' example: cfjspkytaurk - in: query name: sortBy description: 'Must not be greater than 255 characters.' example: xthzgbtryokkocufumdy required: false schema: type: string description: 'Must not be greater than 255 characters.' example: xthzgbtryokkocufumdy - in: query name: sortOrder description: '' example: desc required: false schema: type: string description: '' example: desc enum: - asc - desc - in: query name: filter description: '' example: null required: false schema: type: object description: '' example: null properties: { } - in: query name: filter.search description: 'Must not be greater than 255 characters.' example: iqbxwpwzqioh required: false schema: type: string description: 'Must not be greater than 255 characters.' example: iqbxwpwzqioh - in: query name: filter.active description: '' example: true required: false schema: type: boolean description: '' example: true - in: query name: filter.enabled description: '' example: true required: false schema: type: boolean description: '' example: true responses: 200: description: '' content: application/json: schema: type: object example: data: [] links: first: 'https://tracklabsolar.com/api/v1/type/mobile-os-version?page=1' last: 'https://tracklabsolar.com/api/v1/type/mobile-os-version?page=1' prev: null next: null meta: current_page: 1 from: null last_page: 1 links: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/mobile-os-version?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false path: 'https://tracklabsolar.com/api/v1/type/mobile-os-version' per_page: 20 to: null total: 0 properties: data: type: array example: [] links: type: object properties: first: type: string example: 'https://tracklabsolar.com/api/v1/type/mobile-os-version?page=1' last: type: string example: 'https://tracklabsolar.com/api/v1/type/mobile-os-version?page=1' prev: type: string example: null nullable: true next: type: string example: null nullable: true meta: type: object properties: current_page: type: integer example: 1 from: type: string example: null nullable: true last_page: type: integer example: 1 links: type: array example: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/mobile-os-version?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false items: type: object properties: url: type: string example: null nullable: true label: type: string example: '« Previous' page: type: string example: null nullable: true active: type: boolean example: false path: type: string example: 'https://tracklabsolar.com/api/v1/type/mobile-os-version' per_page: type: integer example: 20 to: type: string example: null nullable: true total: type: integer example: 0 tags: - Endpoints /api/v1/type/mobile-platform: get: summary: '' operationId: getApiV1TypeMobilePlatform description: '' parameters: - in: query name: page description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 required: false schema: type: integer description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 - in: query name: perPage description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 required: false schema: type: integer description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 - in: query name: sort description: 'Must not be greater than 255 characters.' example: iennnggxsadrhyrnrq required: false schema: type: string description: 'Must not be greater than 255 characters.' example: iennnggxsadrhyrnrq - in: query name: sortBy description: 'Must not be greater than 255 characters.' example: ubg required: false schema: type: string description: 'Must not be greater than 255 characters.' example: ubg - in: query name: sortOrder description: '' example: asc required: false schema: type: string description: '' example: asc enum: - asc - desc - in: query name: filter description: '' example: null required: false schema: type: object description: '' example: null properties: { } - in: query name: filter.search description: 'Must not be greater than 255 characters.' example: gcbcxxmnmambuzrmudyukmva required: false schema: type: string description: 'Must not be greater than 255 characters.' example: gcbcxxmnmambuzrmudyukmva - in: query name: filter.active description: '' example: false required: false schema: type: boolean description: '' example: false - in: query name: filter.enabled description: '' example: true required: false schema: type: boolean description: '' example: true responses: 200: description: '' content: application/json: schema: type: object example: data: [] links: first: 'https://tracklabsolar.com/api/v1/type/mobile-platform?page=1' last: 'https://tracklabsolar.com/api/v1/type/mobile-platform?page=1' prev: null next: null meta: current_page: 1 from: null last_page: 1 links: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/mobile-platform?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false path: 'https://tracklabsolar.com/api/v1/type/mobile-platform' per_page: 20 to: null total: 0 properties: data: type: array example: [] links: type: object properties: first: type: string example: 'https://tracklabsolar.com/api/v1/type/mobile-platform?page=1' last: type: string example: 'https://tracklabsolar.com/api/v1/type/mobile-platform?page=1' prev: type: string example: null nullable: true next: type: string example: null nullable: true meta: type: object properties: current_page: type: integer example: 1 from: type: string example: null nullable: true last_page: type: integer example: 1 links: type: array example: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/mobile-platform?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false items: type: object properties: url: type: string example: null nullable: true label: type: string example: '« Previous' page: type: string example: null nullable: true active: type: boolean example: false path: type: string example: 'https://tracklabsolar.com/api/v1/type/mobile-platform' per_page: type: integer example: 20 to: type: string example: null nullable: true total: type: integer example: 0 tags: - Endpoints /api/v1/type/note: get: summary: '' operationId: getApiV1TypeNote description: '' parameters: - in: query name: page description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 required: false schema: type: integer description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 - in: query name: perPage description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 required: false schema: type: integer description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 - in: query name: sort description: 'Must not be greater than 255 characters.' example: dnakedeijdkwkyivorcnkym required: false schema: type: string description: 'Must not be greater than 255 characters.' example: dnakedeijdkwkyivorcnkym - in: query name: sortBy description: 'Must not be greater than 255 characters.' example: iedjubplp required: false schema: type: string description: 'Must not be greater than 255 characters.' example: iedjubplp - in: query name: sortOrder description: '' example: desc required: false schema: type: string description: '' example: desc enum: - asc - desc - in: query name: filter description: '' example: null required: false schema: type: object description: '' example: null properties: { } - in: query name: filter.search description: 'Must not be greater than 255 characters.' example: pabnqxgqchx required: false schema: type: string description: 'Must not be greater than 255 characters.' example: pabnqxgqchx - in: query name: filter.active description: '' example: false required: false schema: type: boolean description: '' example: false - in: query name: filter.enabled description: '' example: false required: false schema: type: boolean description: '' example: false responses: 200: description: '' content: application/json: schema: type: object example: data: [] links: first: 'https://tracklabsolar.com/api/v1/type/note?page=1' last: 'https://tracklabsolar.com/api/v1/type/note?page=1' prev: null next: null meta: current_page: 1 from: null last_page: 1 links: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/note?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false path: 'https://tracklabsolar.com/api/v1/type/note' per_page: 20 to: null total: 0 properties: data: type: array example: [] links: type: object properties: first: type: string example: 'https://tracklabsolar.com/api/v1/type/note?page=1' last: type: string example: 'https://tracklabsolar.com/api/v1/type/note?page=1' prev: type: string example: null nullable: true next: type: string example: null nullable: true meta: type: object properties: current_page: type: integer example: 1 from: type: string example: null nullable: true last_page: type: integer example: 1 links: type: array example: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/note?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false items: type: object properties: url: type: string example: null nullable: true label: type: string example: '« Previous' page: type: string example: null nullable: true active: type: boolean example: false path: type: string example: 'https://tracklabsolar.com/api/v1/type/note' per_page: type: integer example: 20 to: type: string example: null nullable: true total: type: integer example: 0 tags: - Endpoints /api/v1/type/notification-channel: get: summary: '' operationId: getApiV1TypeNotificationChannel description: '' parameters: - in: query name: page description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 required: false schema: type: integer description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 - in: query name: perPage description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 required: false schema: type: integer description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 - in: query name: sort description: 'Must not be greater than 255 characters.' example: iwivarbkpfsquxxnnqvt required: false schema: type: string description: 'Must not be greater than 255 characters.' example: iwivarbkpfsquxxnnqvt - in: query name: sortBy description: 'Must not be greater than 255 characters.' example: vw required: false schema: type: string description: 'Must not be greater than 255 characters.' example: vw - in: query name: sortOrder description: '' example: desc required: false schema: type: string description: '' example: desc enum: - asc - desc - in: query name: filter description: '' example: null required: false schema: type: object description: '' example: null properties: { } - in: query name: filter.search description: 'Must not be greater than 255 characters.' example: aahoh required: false schema: type: string description: 'Must not be greater than 255 characters.' example: aahoh - in: query name: filter.active description: '' example: true required: false schema: type: boolean description: '' example: true - in: query name: filter.enabled description: '' example: true required: false schema: type: boolean description: '' example: true responses: 200: description: '' content: application/json: schema: type: object example: data: [] links: first: 'https://tracklabsolar.com/api/v1/type/notification-channel?page=1' last: 'https://tracklabsolar.com/api/v1/type/notification-channel?page=1' prev: null next: null meta: current_page: 1 from: null last_page: 1 links: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/notification-channel?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false path: 'https://tracklabsolar.com/api/v1/type/notification-channel' per_page: 20 to: null total: 0 properties: data: type: array example: [] links: type: object properties: first: type: string example: 'https://tracklabsolar.com/api/v1/type/notification-channel?page=1' last: type: string example: 'https://tracklabsolar.com/api/v1/type/notification-channel?page=1' prev: type: string example: null nullable: true next: type: string example: null nullable: true meta: type: object properties: current_page: type: integer example: 1 from: type: string example: null nullable: true last_page: type: integer example: 1 links: type: array example: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/notification-channel?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false items: type: object properties: url: type: string example: null nullable: true label: type: string example: '« Previous' page: type: string example: null nullable: true active: type: boolean example: false path: type: string example: 'https://tracklabsolar.com/api/v1/type/notification-channel' per_page: type: integer example: 20 to: type: string example: null nullable: true total: type: integer example: 0 tags: - Endpoints /api/v1/type/notification-delivery-status: get: summary: '' operationId: getApiV1TypeNotificationDeliveryStatus description: '' parameters: - in: query name: page description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 required: false schema: type: integer description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 - in: query name: perPage description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 required: false schema: type: integer description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 - in: query name: sort description: 'Must not be greater than 255 characters.' example: ggsekyupftjizvwkcnohhqm required: false schema: type: string description: 'Must not be greater than 255 characters.' example: ggsekyupftjizvwkcnohhqm - in: query name: sortBy description: 'Must not be greater than 255 characters.' example: ieekmekcwjjrukj required: false schema: type: string description: 'Must not be greater than 255 characters.' example: ieekmekcwjjrukj - in: query name: sortOrder description: '' example: desc required: false schema: type: string description: '' example: desc enum: - asc - desc - in: query name: filter description: '' example: null required: false schema: type: object description: '' example: null properties: { } - in: query name: filter.search description: 'Must not be greater than 255 characters.' example: axnoxgy required: false schema: type: string description: 'Must not be greater than 255 characters.' example: axnoxgy - in: query name: filter.active description: '' example: true required: false schema: type: boolean description: '' example: true - in: query name: filter.enabled description: '' example: true required: false schema: type: boolean description: '' example: true responses: 200: description: '' content: application/json: schema: type: object example: data: [] links: first: 'https://tracklabsolar.com/api/v1/type/notification-delivery-status?page=1' last: 'https://tracklabsolar.com/api/v1/type/notification-delivery-status?page=1' prev: null next: null meta: current_page: 1 from: null last_page: 1 links: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/notification-delivery-status?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false path: 'https://tracklabsolar.com/api/v1/type/notification-delivery-status' per_page: 20 to: null total: 0 properties: data: type: array example: [] links: type: object properties: first: type: string example: 'https://tracklabsolar.com/api/v1/type/notification-delivery-status?page=1' last: type: string example: 'https://tracklabsolar.com/api/v1/type/notification-delivery-status?page=1' prev: type: string example: null nullable: true next: type: string example: null nullable: true meta: type: object properties: current_page: type: integer example: 1 from: type: string example: null nullable: true last_page: type: integer example: 1 links: type: array example: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/notification-delivery-status?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false items: type: object properties: url: type: string example: null nullable: true label: type: string example: '« Previous' page: type: string example: null nullable: true active: type: boolean example: false path: type: string example: 'https://tracklabsolar.com/api/v1/type/notification-delivery-status' per_page: type: integer example: 20 to: type: string example: null nullable: true total: type: integer example: 0 tags: - Endpoints /api/v1/type/notification-template-format: get: summary: '' operationId: getApiV1TypeNotificationTemplateFormat description: '' parameters: - in: query name: page description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 required: false schema: type: integer description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 - in: query name: perPage description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 required: false schema: type: integer description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 - in: query name: sort description: 'Must not be greater than 255 characters.' example: hi required: false schema: type: string description: 'Must not be greater than 255 characters.' example: hi - in: query name: sortBy description: 'Must not be greater than 255 characters.' example: vlch required: false schema: type: string description: 'Must not be greater than 255 characters.' example: vlch - in: query name: sortOrder description: '' example: desc required: false schema: type: string description: '' example: desc enum: - asc - desc - in: query name: filter description: '' example: null required: false schema: type: object description: '' example: null properties: { } - in: query name: filter.search description: 'Must not be greater than 255 characters.' example: khaiylqmx required: false schema: type: string description: 'Must not be greater than 255 characters.' example: khaiylqmx - in: query name: filter.active description: '' example: false required: false schema: type: boolean description: '' example: false - in: query name: filter.enabled description: '' example: false required: false schema: type: boolean description: '' example: false responses: 200: description: '' content: application/json: schema: type: object example: data: [] links: first: 'https://tracklabsolar.com/api/v1/type/notification-template-format?page=1' last: 'https://tracklabsolar.com/api/v1/type/notification-template-format?page=1' prev: null next: null meta: current_page: 1 from: null last_page: 1 links: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/notification-template-format?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false path: 'https://tracklabsolar.com/api/v1/type/notification-template-format' per_page: 20 to: null total: 0 properties: data: type: array example: [] links: type: object properties: first: type: string example: 'https://tracklabsolar.com/api/v1/type/notification-template-format?page=1' last: type: string example: 'https://tracklabsolar.com/api/v1/type/notification-template-format?page=1' prev: type: string example: null nullable: true next: type: string example: null nullable: true meta: type: object properties: current_page: type: integer example: 1 from: type: string example: null nullable: true last_page: type: integer example: 1 links: type: array example: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/notification-template-format?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false items: type: object properties: url: type: string example: null nullable: true label: type: string example: '« Previous' page: type: string example: null nullable: true active: type: boolean example: false path: type: string example: 'https://tracklabsolar.com/api/v1/type/notification-template-format' per_page: type: integer example: 20 to: type: string example: null nullable: true total: type: integer example: 0 tags: - Endpoints /api/v1/type/permission: get: summary: '' operationId: getApiV1TypePermission description: '' parameters: - in: query name: page description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 required: false schema: type: integer description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 - in: query name: perPage description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 required: false schema: type: integer description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 - in: query name: sort description: 'Must not be greater than 255 characters.' example: unazabqeojsabekcekglfur required: false schema: type: string description: 'Must not be greater than 255 characters.' example: unazabqeojsabekcekglfur - in: query name: sortBy description: 'Must not be greater than 255 characters.' example: qojasjeurieqscf required: false schema: type: string description: 'Must not be greater than 255 characters.' example: qojasjeurieqscf - in: query name: sortOrder description: '' example: asc required: false schema: type: string description: '' example: asc enum: - asc - desc - in: query name: filter description: '' example: null required: false schema: type: object description: '' example: null properties: { } - in: query name: filter.search description: 'Must not be greater than 255 characters.' example: pxynistwlz required: false schema: type: string description: 'Must not be greater than 255 characters.' example: pxynistwlz - in: query name: filter.active description: '' example: true required: false schema: type: boolean description: '' example: true - in: query name: filter.enabled description: '' example: true required: false schema: type: boolean description: '' example: true responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints /api/v1/type/rma-status: get: summary: '' operationId: getApiV1TypeRmaStatus description: '' parameters: - in: query name: page description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 required: false schema: type: integer description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 - in: query name: perPage description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 required: false schema: type: integer description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 - in: query name: sort description: 'Must not be greater than 255 characters.' example: cilwxevzruu required: false schema: type: string description: 'Must not be greater than 255 characters.' example: cilwxevzruu - in: query name: sortBy description: 'Must not be greater than 255 characters.' example: onwuhvmlrjnakljwhqovbisf required: false schema: type: string description: 'Must not be greater than 255 characters.' example: onwuhvmlrjnakljwhqovbisf - in: query name: sortOrder description: '' example: desc required: false schema: type: string description: '' example: desc enum: - asc - desc - in: query name: filter description: '' example: null required: false schema: type: object description: '' example: null properties: { } - in: query name: filter.search description: 'Must not be greater than 255 characters.' example: brrycgb required: false schema: type: string description: 'Must not be greater than 255 characters.' example: brrycgb - in: query name: filter.active description: '' example: false required: false schema: type: boolean description: '' example: false - in: query name: filter.enabled description: '' example: false required: false schema: type: boolean description: '' example: false responses: 200: description: '' content: application/json: schema: type: object example: data: [] links: first: 'https://tracklabsolar.com/api/v1/type/rma-status?page=1' last: 'https://tracklabsolar.com/api/v1/type/rma-status?page=1' prev: null next: null meta: current_page: 1 from: null last_page: 1 links: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/rma-status?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false path: 'https://tracklabsolar.com/api/v1/type/rma-status' per_page: 20 to: null total: 0 properties: data: type: array example: [] links: type: object properties: first: type: string example: 'https://tracklabsolar.com/api/v1/type/rma-status?page=1' last: type: string example: 'https://tracklabsolar.com/api/v1/type/rma-status?page=1' prev: type: string example: null nullable: true next: type: string example: null nullable: true meta: type: object properties: current_page: type: integer example: 1 from: type: string example: null nullable: true last_page: type: integer example: 1 links: type: array example: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/rma-status?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false items: type: object properties: url: type: string example: null nullable: true label: type: string example: '« Previous' page: type: string example: null nullable: true active: type: boolean example: false path: type: string example: 'https://tracklabsolar.com/api/v1/type/rma-status' per_page: type: integer example: 20 to: type: string example: null nullable: true total: type: integer example: 0 tags: - Endpoints /api/v1/type/role: get: summary: '' operationId: getApiV1TypeRole description: '' parameters: - in: query name: page description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 required: false schema: type: integer description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 - in: query name: perPage description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 required: false schema: type: integer description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 - in: query name: sort description: 'Must not be greater than 255 characters.' example: smot required: false schema: type: string description: 'Must not be greater than 255 characters.' example: smot - in: query name: sortBy description: 'Must not be greater than 255 characters.' example: dck required: false schema: type: string description: 'Must not be greater than 255 characters.' example: dck - in: query name: sortOrder description: '' example: asc required: false schema: type: string description: '' example: asc enum: - asc - desc - in: query name: filter description: '' example: null required: false schema: type: object description: '' example: null properties: { } - in: query name: filter.search description: 'Must not be greater than 255 characters.' example: uvcxpkxpnc required: false schema: type: string description: 'Must not be greater than 255 characters.' example: uvcxpkxpnc - in: query name: filter.active description: '' example: true required: false schema: type: boolean description: '' example: true - in: query name: filter.enabled description: '' example: true required: false schema: type: boolean description: '' example: true responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Endpoints /api/v1/type/user-address: get: summary: '' operationId: getApiV1TypeUserAddress description: '' parameters: - in: query name: page description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 required: false schema: type: integer description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 - in: query name: perPage description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 required: false schema: type: integer description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 - in: query name: sort description: 'Must not be greater than 255 characters.' example: jsqek required: false schema: type: string description: 'Must not be greater than 255 characters.' example: jsqek - in: query name: sortBy description: 'Must not be greater than 255 characters.' example: s required: false schema: type: string description: 'Must not be greater than 255 characters.' example: s - in: query name: sortOrder description: '' example: asc required: false schema: type: string description: '' example: asc enum: - asc - desc - in: query name: filter description: '' example: null required: false schema: type: object description: '' example: null properties: { } - in: query name: filter.search description: 'Must not be greater than 255 characters.' example: nfuzgxynhwowyvrnjqhfuzufj required: false schema: type: string description: 'Must not be greater than 255 characters.' example: nfuzgxynhwowyvrnjqhfuzufj - in: query name: filter.active description: '' example: true required: false schema: type: boolean description: '' example: true - in: query name: filter.enabled description: '' example: true required: false schema: type: boolean description: '' example: true responses: 200: description: '' content: application/json: schema: type: object example: data: [] links: first: 'https://tracklabsolar.com/api/v1/type/user-address?page=1' last: 'https://tracklabsolar.com/api/v1/type/user-address?page=1' prev: null next: null meta: current_page: 1 from: null last_page: 1 links: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/user-address?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false path: 'https://tracklabsolar.com/api/v1/type/user-address' per_page: 20 to: null total: 0 properties: data: type: array example: [] links: type: object properties: first: type: string example: 'https://tracklabsolar.com/api/v1/type/user-address?page=1' last: type: string example: 'https://tracklabsolar.com/api/v1/type/user-address?page=1' prev: type: string example: null nullable: true next: type: string example: null nullable: true meta: type: object properties: current_page: type: integer example: 1 from: type: string example: null nullable: true last_page: type: integer example: 1 links: type: array example: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/user-address?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false items: type: object properties: url: type: string example: null nullable: true label: type: string example: '« Previous' page: type: string example: null nullable: true active: type: boolean example: false path: type: string example: 'https://tracklabsolar.com/api/v1/type/user-address' per_page: type: integer example: 20 to: type: string example: null nullable: true total: type: integer example: 0 tags: - Endpoints /api/v1/type/warranty: get: summary: '' operationId: getApiV1TypeWarranty description: '' parameters: - in: query name: page description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 required: false schema: type: integer description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 - in: query name: perPage description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 required: false schema: type: integer description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 20 - in: query name: sort description: 'Must not be greater than 255 characters.' example: adnulcz required: false schema: type: string description: 'Must not be greater than 255 characters.' example: adnulcz - in: query name: sortBy description: 'Must not be greater than 255 characters.' example: khylmnqnwy required: false schema: type: string description: 'Must not be greater than 255 characters.' example: khylmnqnwy - in: query name: sortOrder description: '' example: asc required: false schema: type: string description: '' example: asc enum: - asc - desc - in: query name: filter description: '' example: null required: false schema: type: object description: '' example: null properties: { } - in: query name: filter.search description: 'Must not be greater than 255 characters.' example: szelqpxtq required: false schema: type: string description: 'Must not be greater than 255 characters.' example: szelqpxtq - in: query name: filter.active description: '' example: true required: false schema: type: boolean description: '' example: true - in: query name: filter.enabled description: '' example: false required: false schema: type: boolean description: '' example: false responses: 200: description: '' content: application/json: schema: type: object example: data: [] links: first: 'https://tracklabsolar.com/api/v1/type/warranty?page=1' last: 'https://tracklabsolar.com/api/v1/type/warranty?page=1' prev: null next: null meta: current_page: 1 from: null last_page: 1 links: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/warranty?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false path: 'https://tracklabsolar.com/api/v1/type/warranty' per_page: 20 to: null total: 0 properties: data: type: array example: [] links: type: object properties: first: type: string example: 'https://tracklabsolar.com/api/v1/type/warranty?page=1' last: type: string example: 'https://tracklabsolar.com/api/v1/type/warranty?page=1' prev: type: string example: null nullable: true next: type: string example: null nullable: true meta: type: object properties: current_page: type: integer example: 1 from: type: string example: null nullable: true last_page: type: integer example: 1 links: type: array example: - url: null label: '« Previous' page: null active: false - url: 'https://tracklabsolar.com/api/v1/type/warranty?page=1' label: '1' page: 1 active: true - url: null label: 'Next »' page: null active: false items: type: object properties: url: type: string example: null nullable: true label: type: string example: '« Previous' page: type: string example: null nullable: true active: type: boolean example: false path: type: string example: 'https://tracklabsolar.com/api/v1/type/warranty' per_page: type: integer example: 20 to: type: string example: null nullable: true total: type: integer example: 0 tags: - Endpoints /api/v1/type/country: get: summary: 'Get Country Types' operationId: getCountryTypes description: '' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: - isoCode: '' isoThreeCode: '' name: Unknown officialName: Unknown emoji: '' enabled: true isActive: false - isoCode: '' isoThreeCode: '' name: Unknown officialName: Unknown emoji: '' enabled: true isActive: false properties: data: type: array example: - isoCode: '' isoThreeCode: '' name: Unknown officialName: Unknown emoji: '' enabled: true isActive: false - isoCode: '' isoThreeCode: '' name: Unknown officialName: Unknown emoji: '' enabled: true isActive: false items: type: object properties: isoCode: type: string example: '' isoThreeCode: type: string example: '' name: type: string example: Unknown officialName: type: string example: Unknown emoji: type: string example: '' enabled: type: boolean example: true isActive: type: boolean example: false tags: - Endpoints /api/v1/type/country/detailed: get: summary: 'Get Detailed Country Types' operationId: getDetailedCountryTypes description: '' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: - isoCode: '' isoThreeCode: '' isoNumeric: 0 name: Unknown officialName: Unknown emoji: '' enabled: true isActive: false latitude: 0 longitude: 0 latitudeMin: 0 latitudeMax: 0 longitudeMin: 0 longitudeMax: 0 currencies: - code: UNKNOWN name: Unknown symbol: Ζ’ decimalPlaces: 0 isActive: false languages: - code: null name: Unknown nativeName: null isActive: false timezones: - identifier: Unknown name: Unknown utcOffset: 0 isActive: false - isoCode: '' isoThreeCode: '' isoNumeric: 0 name: Unknown officialName: Unknown emoji: '' enabled: true isActive: false latitude: 0 longitude: 0 latitudeMin: 0 latitudeMax: 0 longitudeMin: 0 longitudeMax: 0 currencies: - code: UNKNOWN name: Unknown symbol: Ζ’ decimalPlaces: 0 isActive: false languages: - code: null name: Unknown nativeName: null isActive: false timezones: - identifier: Unknown name: Unknown utcOffset: 0 isActive: false properties: data: type: array example: - isoCode: '' isoThreeCode: '' isoNumeric: 0 name: Unknown officialName: Unknown emoji: '' enabled: true isActive: false latitude: 0 longitude: 0 latitudeMin: 0 latitudeMax: 0 longitudeMin: 0 longitudeMax: 0 currencies: - code: UNKNOWN name: Unknown symbol: Ζ’ decimalPlaces: 0 isActive: false languages: - code: null name: Unknown nativeName: null isActive: false timezones: - identifier: Unknown name: Unknown utcOffset: 0 isActive: false - isoCode: '' isoThreeCode: '' isoNumeric: 0 name: Unknown officialName: Unknown emoji: '' enabled: true isActive: false latitude: 0 longitude: 0 latitudeMin: 0 latitudeMax: 0 longitudeMin: 0 longitudeMax: 0 currencies: - code: UNKNOWN name: Unknown symbol: Ζ’ decimalPlaces: 0 isActive: false languages: - code: null name: Unknown nativeName: null isActive: false timezones: - identifier: Unknown name: Unknown utcOffset: 0 isActive: false items: type: object properties: isoCode: type: string example: '' isoThreeCode: type: string example: '' isoNumeric: type: integer example: 0 name: type: string example: Unknown officialName: type: string example: Unknown emoji: type: string example: '' enabled: type: boolean example: true isActive: type: boolean example: false latitude: type: integer example: 0 longitude: type: integer example: 0 latitudeMin: type: integer example: 0 latitudeMax: type: integer example: 0 longitudeMin: type: integer example: 0 longitudeMax: type: integer example: 0 currencies: type: array example: - code: UNKNOWN name: Unknown symbol: Ζ’ decimalPlaces: 0 isActive: false items: type: object properties: code: type: string example: UNKNOWN name: type: string example: Unknown symbol: type: string example: Ζ’ decimalPlaces: type: integer example: 0 isActive: type: boolean example: false languages: type: array example: - code: null name: Unknown nativeName: null isActive: false items: type: object properties: code: type: string example: null nullable: true name: type: string example: Unknown nativeName: type: string example: null nullable: true isActive: type: boolean example: false timezones: type: array example: - identifier: Unknown name: Unknown utcOffset: 0 isActive: false items: type: object properties: identifier: type: string example: Unknown name: type: string example: Unknown utcOffset: type: integer example: 0 isActive: type: boolean example: false tags: - Endpoints '/api/v1/type/country/{isoCode}': get: summary: 'Get Single Country Full Details' operationId: getSingleCountryFullDetails description: '' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: isoCode: '' isoThreeCode: '' isoNumeric: 0 name: Unknown officialName: Unknown emoji: '' enabled: true isActive: false latitude: 0 longitude: 0 latitudeMin: 0 latitudeMax: 0 longitudeMin: 0 longitudeMax: 0 continent: name: None currencies: - code: UNKNOWN name: Unknown symbol: Ζ’ decimalPlaces: 0 isActive: false languages: - code: null name: Unknown nativeName: null isActive: false timezones: - identifier: Unknown name: Unknown utcOffset: 0 isActive: false regions: - name: Unknown isActive: false extras: null properties: data: type: object properties: isoCode: type: string example: '' isoThreeCode: type: string example: '' isoNumeric: type: integer example: 0 name: type: string example: Unknown officialName: type: string example: Unknown emoji: type: string example: '' enabled: type: boolean example: true isActive: type: boolean example: false latitude: type: integer example: 0 longitude: type: integer example: 0 latitudeMin: type: integer example: 0 latitudeMax: type: integer example: 0 longitudeMin: type: integer example: 0 longitudeMax: type: integer example: 0 continent: type: object properties: name: type: string example: None currencies: type: array example: - code: UNKNOWN name: Unknown symbol: Ζ’ decimalPlaces: 0 isActive: false items: type: object properties: code: type: string example: UNKNOWN name: type: string example: Unknown symbol: type: string example: Ζ’ decimalPlaces: type: integer example: 0 isActive: type: boolean example: false languages: type: array example: - code: null name: Unknown nativeName: null isActive: false items: type: object properties: code: type: string example: null nullable: true name: type: string example: Unknown nativeName: type: string example: null nullable: true isActive: type: boolean example: false timezones: type: array example: - identifier: Unknown name: Unknown utcOffset: 0 isActive: false items: type: object properties: identifier: type: string example: Unknown name: type: string example: Unknown utcOffset: type: integer example: 0 isActive: type: boolean example: false regions: type: array example: - name: Unknown isActive: false items: type: object properties: name: type: string example: Unknown isActive: type: boolean example: false extras: type: string example: null nullable: true tags: - Endpoints parameters: - in: path name: isoCode description: 'The ISO 3166-1 alpha-2 country code.' example: ZA required: true schema: type: string /api/v1/type/data: get: summary: 'Get Data Types' operationId: getDataTypes description: '' parameters: [] responses: 200: description: '' content: application/json: schema: oneOf: - description: '' type: object example: data: - slug: unknown name: unknown description: '' - slug: unknown name: unknown description: '' properties: data: type: array example: - slug: unknown name: unknown description: '' - slug: unknown name: unknown description: '' items: type: object properties: slug: type: string example: unknown name: type: string example: unknown description: type: string example: '' - description: '' type: object example: data: - slug: numeric name: Numeric description: 'Numeric data type' - slug: string name: String description: 'String data type' properties: data: type: array example: - slug: numeric name: Numeric description: 'Numeric data type' - slug: string name: String description: 'String data type' items: type: object properties: slug: type: string example: numeric name: type: string example: Numeric description: type: string example: 'Numeric data type' tags: - Endpoints /api/v1/type/data/units: get: summary: 'Get Data Unit Types' operationId: getDataUnitTypes description: '' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: - slug: unknown dataTypeSlug: unknown name: Unknown unit: '' description: '' - slug: unknown dataTypeSlug: unknown name: Unknown unit: '' description: '' properties: data: type: array example: - slug: unknown dataTypeSlug: unknown name: Unknown unit: '' description: '' - slug: unknown dataTypeSlug: unknown name: Unknown unit: '' description: '' items: type: object properties: slug: type: string example: unknown dataTypeSlug: type: string example: unknown name: type: string example: Unknown unit: type: string example: '' description: type: string example: '' tags: - Endpoints /api/v1/type/data/parameter: get: summary: 'Get Parameter Types' operationId: getParameterTypes description: '' parameters: [] responses: 200: description: '' content: application/json: schema: oneOf: - description: '' type: object example: data: - slug: unknown name: Unknown description: '' dataUnitSlug: unknown dataTypeSlug: unknown unit: '' orderColumn: 0 enabled: true isReadOnly: false collectorTypeSlug: null validation: [] lookups: null - slug: unknown name: Unknown description: '' dataUnitSlug: unknown dataTypeSlug: unknown unit: '' orderColumn: 0 enabled: true isReadOnly: false collectorTypeSlug: null validation: [] lookups: null properties: data: type: array example: - slug: unknown name: Unknown description: '' dataUnitSlug: unknown dataTypeSlug: unknown unit: '' orderColumn: 0 enabled: true isReadOnly: false collectorTypeSlug: null validation: [] lookups: null - slug: unknown name: Unknown description: '' dataUnitSlug: unknown dataTypeSlug: unknown unit: '' orderColumn: 0 enabled: true isReadOnly: false collectorTypeSlug: null validation: [] lookups: null items: type: object properties: slug: type: string example: unknown name: type: string example: Unknown description: type: string example: '' dataUnitSlug: type: string example: unknown dataTypeSlug: type: string example: unknown unit: type: string example: '' orderColumn: type: integer example: 0 enabled: type: boolean example: true isReadOnly: type: boolean example: false collectorTypeSlug: type: string example: null nullable: true validation: type: array example: [] lookups: type: string example: null nullable: true - description: '' type: object example: data: - slug: battery_level dataUnitSlug: percentage dataTypeSlug: numeric unit: '%' name: 'Battery Level' description: 'Device battery level' properties: data: type: array example: - slug: battery_level dataUnitSlug: percentage dataTypeSlug: numeric unit: '%' name: 'Battery Level' description: 'Device battery level' items: type: object properties: slug: type: string example: battery_level dataUnitSlug: type: string example: percentage dataTypeSlug: type: string example: numeric unit: type: string example: '%' name: type: string example: 'Battery Level' description: type: string example: 'Device battery level' tags: - Endpoints /api/v1/type/data/measurement: get: summary: 'Get Measurement Types' operationId: getMeasurementTypes description: 'Retrieve all available measurement types for collectors.' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: - uuid: 550e8400-e29b-41d4-a716-446655440000 name: Temperature slug: temperature description: 'Temperature measurements' data_type: uuid: 550e8400-e29b-41d4-a716-446655440000 name: Numeric slug: numeric data_unit: uuid: 550e8400-e29b-41d4-a716-446655440000 name: Celsius slug: celsius symbol: Β°C properties: data: type: array example: - uuid: 550e8400-e29b-41d4-a716-446655440000 name: Temperature slug: temperature description: 'Temperature measurements' data_type: uuid: 550e8400-e29b-41d4-a716-446655440000 name: Numeric slug: numeric data_unit: uuid: 550e8400-e29b-41d4-a716-446655440000 name: Celsius slug: celsius symbol: Β°C items: type: object properties: uuid: type: string example: 550e8400-e29b-41d4-a716-446655440000 name: type: string example: Temperature slug: type: string example: temperature description: type: string example: 'Temperature measurements' data_type: type: object properties: uuid: type: string example: 550e8400-e29b-41d4-a716-446655440000 name: type: string example: Numeric slug: type: string example: numeric data_unit: type: object properties: uuid: type: string example: 550e8400-e29b-41d4-a716-446655440000 name: type: string example: Celsius slug: type: string example: celsius symbol: type: string example: Β°C tags: - Endpoints /api/v1/type/data/measurement-aggregation: get: summary: '' operationId: getApiV1TypeDataMeasurementAggregation description: '' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: avg: slug: avg name: Average description: 'Mean + stddev + kurtosis (default)' orderColumn: 1 requiresNumericData: true median: slug: median name: Median description: 'Median (50th percentile)' orderColumn: 2 requiresNumericData: true min: slug: min name: Minimum description: 'Minimum value in bucket' orderColumn: 3 requiresNumericData: true max: slug: max name: Maximum description: 'Maximum value in bucket' orderColumn: 4 requiresNumericData: true sum: slug: sum name: Sum description: 'Sum of all values' orderColumn: 5 requiresNumericData: true count: slug: count name: Count description: 'Number of data points' orderColumn: 6 requiresNumericData: false first: slug: first name: First description: 'First value by timestamp' orderColumn: 7 requiresNumericData: false last: slug: last name: Last description: 'Last value by timestamp' orderColumn: 8 requiresNumericData: false properties: data: type: object properties: avg: type: object properties: slug: type: string example: avg name: type: string example: Average description: type: string example: 'Mean + stddev + kurtosis (default)' orderColumn: type: integer example: 1 requiresNumericData: type: boolean example: true median: type: object properties: slug: type: string example: median name: type: string example: Median description: type: string example: 'Median (50th percentile)' orderColumn: type: integer example: 2 requiresNumericData: type: boolean example: true min: type: object properties: slug: type: string example: min name: type: string example: Minimum description: type: string example: 'Minimum value in bucket' orderColumn: type: integer example: 3 requiresNumericData: type: boolean example: true max: type: object properties: slug: type: string example: max name: type: string example: Maximum description: type: string example: 'Maximum value in bucket' orderColumn: type: integer example: 4 requiresNumericData: type: boolean example: true sum: type: object properties: slug: type: string example: sum name: type: string example: Sum description: type: string example: 'Sum of all values' orderColumn: type: integer example: 5 requiresNumericData: type: boolean example: true count: type: object properties: slug: type: string example: count name: type: string example: Count description: type: string example: 'Number of data points' orderColumn: type: integer example: 6 requiresNumericData: type: boolean example: false first: type: object properties: slug: type: string example: first name: type: string example: First description: type: string example: 'First value by timestamp' orderColumn: type: integer example: 7 requiresNumericData: type: boolean example: false last: type: object properties: slug: type: string example: last name: type: string example: Last description: type: string example: 'Last value by timestamp' orderColumn: type: integer example: 8 requiresNumericData: type: boolean example: false tags: - Endpoints /api/v1/type/data/period: get: summary: '' operationId: getApiV1TypeDataPeriod description: '' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: - slug: none name: 'No Aggregation' interval: '00:00:01' order: -10 - slug: 1-minute name: '1 Minute' interval: '00:01:00' order: 0 - slug: 10-minutes name: '10 Minutes' interval: '00:10:00' order: 10 - slug: 1-hour name: '1 Hour' interval: '01:00:00' order: 20 - slug: 4-hours name: '4 Hours' interval: '04:00:00' order: 30 - slug: 12-hours name: '12 Hours' interval: '12:00:00' order: 40 - slug: 1-day name: '1 Day' interval: '1 day' order: 50 - slug: 1-week name: '1 Week' interval: '7 days' order: 60 - slug: 1-month name: '1 Month' interval: '1 mon' order: 70 properties: data: type: array example: - slug: none name: 'No Aggregation' interval: '00:00:01' order: -10 - slug: 1-minute name: '1 Minute' interval: '00:01:00' order: 0 - slug: 10-minutes name: '10 Minutes' interval: '00:10:00' order: 10 - slug: 1-hour name: '1 Hour' interval: '01:00:00' order: 20 - slug: 4-hours name: '4 Hours' interval: '04:00:00' order: 30 - slug: 12-hours name: '12 Hours' interval: '12:00:00' order: 40 - slug: 1-day name: '1 Day' interval: '1 day' order: 50 - slug: 1-week name: '1 Week' interval: '7 days' order: 60 - slug: 1-month name: '1 Month' interval: '1 mon' order: 70 items: type: object properties: slug: type: string example: none name: type: string example: 'No Aggregation' interval: type: string example: '00:00:01' order: type: integer example: -10 tags: - Endpoints /api/v1/type/data/environment: get: summary: '' operationId: getApiV1TypeDataEnvironment description: '' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: production: slug: production name: Production description: 'Production environment' staging: slug: staging name: Staging description: 'Staging environment' development: slug: development name: Development description: 'Development environment' properties: data: type: object properties: production: type: object properties: slug: type: string example: production name: type: string example: Production description: type: string example: 'Production environment' staging: type: object properties: slug: type: string example: staging name: type: string example: Staging description: type: string example: 'Staging environment' development: type: object properties: slug: type: string example: development name: type: string example: Development description: type: string example: 'Development environment' tags: - Endpoints /api/v1/type/data/device-message-processing-error: get: summary: '' operationId: getApiV1TypeDataDeviceMessageProcessingError description: '' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: collector-not-found: slug: collector-not-found name: 'Collector Not Found' description: 'No collector found for the given serial number' database-error: slug: database-error name: 'Database Error' description: 'Database operation failed during processing' invalid-message-structure: slug: invalid-message-structure name: 'Invalid Message Structure' description: 'Message JSON structure is invalid or missing required fields' json-parsing-error: slug: json-parsing-error name: 'JSON Parsing Error' description: 'Failed to parse message JSON' measurement-type-not-found: slug: measurement-type-not-found name: 'Measurement Type Not Found' description: 'Measurement type slug not found in measurement types table' parameter-type-not-found: slug: parameter-type-not-found name: 'Parameter Type Not Found' description: 'Parameter type slug not found in parameter types table' properties: data: type: object properties: collector-not-found: type: object properties: slug: type: string example: collector-not-found name: type: string example: 'Collector Not Found' description: type: string example: 'No collector found for the given serial number' database-error: type: object properties: slug: type: string example: database-error name: type: string example: 'Database Error' description: type: string example: 'Database operation failed during processing' invalid-message-structure: type: object properties: slug: type: string example: invalid-message-structure name: type: string example: 'Invalid Message Structure' description: type: string example: 'Message JSON structure is invalid or missing required fields' json-parsing-error: type: object properties: slug: type: string example: json-parsing-error name: type: string example: 'JSON Parsing Error' description: type: string example: 'Failed to parse message JSON' measurement-type-not-found: type: object properties: slug: type: string example: measurement-type-not-found name: type: string example: 'Measurement Type Not Found' description: type: string example: 'Measurement type slug not found in measurement types table' parameter-type-not-found: type: object properties: slug: type: string example: parameter-type-not-found name: type: string example: 'Parameter Type Not Found' description: type: string example: 'Parameter type slug not found in parameter types table' tags: - Endpoints /api/v1/type/user-status: get: summary: 'Get User Status Types' operationId: getUserStatusTypes description: 'Returns all enabled user status types ordered by order_column.' parameters: [] responses: 200: description: '' content: application/json: schema: oneOf: - description: '' type: object example: data: - slug: pending name: Pending enabled: true orderColumn: 1 - slug: pending name: Pending enabled: true orderColumn: 1 properties: data: type: array example: - slug: pending name: Pending enabled: true orderColumn: 1 - slug: pending name: Pending enabled: true orderColumn: 1 items: type: object properties: slug: type: string example: pending name: type: string example: Pending enabled: type: boolean example: true orderColumn: type: integer example: 1 - description: '' type: object example: data: - slug: pending name: Pending enabled: true orderColumn: 1 - slug: active name: Active enabled: true orderColumn: 2 properties: data: type: array example: - slug: pending name: Pending enabled: true orderColumn: 1 - slug: active name: Active enabled: true orderColumn: 2 items: type: object properties: slug: type: string example: pending name: type: string example: Pending enabled: type: boolean example: true orderColumn: type: integer example: 1 tags: - Endpoints /api/v1/register: post: summary: 'Handle an incoming registration request.' operationId: handleAnIncomingRegistrationRequest description: '' parameters: [] responses: 201: description: '' content: application/json: schema: type: object example: data: uuid: b11fab33-a56a-4a78-a3c1-b9d324c6aacd createdAt: '2025-11-12T20:27:08+00:00' updatedAt: '2026-02-10T15:20:26+00:00' defaultCompanySlug: null emailVerifiedAt: null defaultCountryIsoCode: '' defaultCountryEmoji: '' email: liquid.ideas@gmail.com firstName: Jo lastName: Whitehouse phoneNumbers: [] roles: [] imgUrl: null imgThumbUrl: null imgLargeUrl: null imgUrlExpiresAt: null isActive: true disabledAt: null status: null statusName: null properties: data: type: object properties: uuid: type: string example: b11fab33-a56a-4a78-a3c1-b9d324c6aacd createdAt: type: string example: '2025-11-12T20:27:08+00:00' updatedAt: type: string example: '2026-02-10T15:20:26+00:00' defaultCompanySlug: type: string example: null nullable: true emailVerifiedAt: type: string example: null nullable: true defaultCountryIsoCode: type: string example: '' defaultCountryEmoji: type: string example: '' email: type: string example: liquid.ideas@gmail.com firstName: type: string example: Jo lastName: type: string example: Whitehouse phoneNumbers: type: array example: [] roles: type: array example: [] imgUrl: type: string example: null nullable: true imgThumbUrl: type: string example: null nullable: true imgLargeUrl: type: string example: null nullable: true imgUrlExpiresAt: type: string example: null nullable: true isActive: type: boolean example: true disabledAt: type: string example: null nullable: true status: type: string example: null nullable: true statusName: type: string example: null nullable: true tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: companyName: type: string description: 'Name of the new company. Must be at least 2 characters.' example: 'My Awesome Company' firstName: type: string description: 'First name of the primary user. Must not be greater than 255 characters.' example: Jane lastName: type: string description: 'Last name of the primary user. Must not be greater than 255 characters.' example: Smith email: type: string description: 'Email address for the primary user. Must be a valid email address. Must not be greater than 255 characters.' example: jane.smith@example.com password: type: string description: 'Password for the primary user (min 10 chars).' example: 'StrongPass123!@#' countryIsoCode: type: string description: 'ISO code of the user/company country. The iso_code of an existing record in the countries table.' example: GB phoneNumber: type: string description: 'Phone number for the primary user. Must be at least 6 characters.' example: '+447123456789' required: - companyName - firstName - lastName - email - password - countryIsoCode - phoneNumber /api/v1/forgot-password: post: summary: 'Handle an incoming password reset link request.' operationId: handleAnIncomingPasswordResetLinkRequest description: '' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: status: 'We have emailed your password reset link.' properties: status: type: string example: 'We have emailed your password reset link.' 422: description: '' content: application/json: schema: type: object example: message: 'The given data was invalid.' errors: email: - "We can't find a user with that email address." properties: message: type: string example: 'The given data was invalid.' errors: type: object properties: email: type: array example: - "We can't find a user with that email address." items: type: string tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: email: type: string description: 'Email address to send the reset link to. Must be a valid email address.' example: user@example.com required: - email /api/v1/reset-password: post: summary: 'Handle an incoming new password request.' operationId: handleAnIncomingNewPasswordRequest description: '' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: status: 'Your password has been reset.' properties: status: type: string example: 'Your password has been reset.' 422: description: '' content: application/json: schema: type: object example: message: 'The given data was invalid.' errors: email: - "We can't find a user with that email address." properties: message: type: string example: 'The given data was invalid.' errors: type: object properties: email: type: array example: - "We can't find a user with that email address." items: type: string tags: - Endpoints requestBody: required: true content: application/json: schema: type: object properties: token: type: string description: 'The password reset token.' example: ... email: type: string description: 'The email address associated with the token. Must be a valid email address.' example: user@example.com password: type: string description: 'The new password.' example: NewSecurePass123! required: - token - email - password '/api/v1/verify-email/{id}/{hash}': get: summary: "Mark the user's email address as verified." operationId: markTheUsersEmailAddressAsVerified description: '' parameters: [] responses: 302: description: '' content: text/plain: schema: type: string example: "\n\n \n \n \n\n Redirecting to https://tracklabsolar.com/emailVerification?error=invalid&msg=Invalid+verification+link\n \n \n Redirecting to https://tracklabsolar.com/emailVerification?error=invalid&msg=Invalid+verification+link.\n \n" tags: - Endpoints parameters: - in: path name: id description: 'The ID of the verify email.' example: quas required: true schema: type: string - in: path name: hash description: '' example: dolor required: true schema: type: string '/api/v1/invitations/{token}': get: summary: 'Get invitation details by token.' operationId: getInvitationDetailsByToken description: "Public endpoint - no authentication required.\nReturns invitation details for display before acceptance." parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: email: user@example.com companyName: 'Example Company' roleName: user invitedBy: 'John Doe' status: pending validUntil: '2026-01-27T12:00:00Z' isExpired: false properties: data: type: object properties: email: type: string example: user@example.com companyName: type: string example: 'Example Company' roleName: type: string example: user invitedBy: type: string example: 'John Doe' status: type: string example: pending validUntil: type: string example: '2026-01-27T12:00:00Z' isExpired: type: boolean example: false tags: - Invitations parameters: - in: path name: token description: '' example: tempore required: true schema: type: string '/api/v1/invitations/{token}/accept': post: summary: 'Accept an invitation.' operationId: acceptAnInvitation description: "Requires authentication. Adds the authenticated user to the company\nwith the pre-assigned role from the invitation." parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: uuid: null email: null status: null roleSlug: null invitedBy: uuid: null name: null validUntil: '2026-03-26T23:05:11+00:00' acceptedAt: null createdAt: '2026-03-26T23:05:11+00:00' properties: data: type: object properties: uuid: type: string example: null nullable: true email: type: string example: null nullable: true status: type: string example: null nullable: true roleSlug: type: string example: null nullable: true invitedBy: type: object properties: uuid: type: string example: null nullable: true name: type: string example: null nullable: true validUntil: type: string example: '2026-03-26T23:05:11+00:00' acceptedAt: type: string example: null nullable: true createdAt: type: string example: '2026-03-26T23:05:11+00:00' tags: - Invitations parameters: - in: path name: token description: '' example: deserunt required: true schema: type: string /api/v1/sa/activity-logs: get: summary: 'List all activity logs (global scope).' operationId: listAllActivityLogsglobalScope description: "Returns paginated activity logs with optional filtering by event type,\naction, date range, causer, and other parameters." parameters: - in: query name: page description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 required: false schema: type: integer description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 - in: query name: perPage description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 25 required: false schema: type: integer description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 25 - in: query name: event description: 'Filter by event category (e.g., "sa.device-model-type"). Must not be greater than 255 characters.' example: sa.device-model-type required: false schema: type: string description: 'Filter by event category (e.g., "sa.device-model-type"). Must not be greater than 255 characters.' example: sa.device-model-type nullable: true - in: query name: action description: 'Filter by action type (e.g., "create", "update", "delete"). Must not be greater than 255 characters.' example: create required: false schema: type: string description: 'Filter by action type (e.g., "create", "update", "delete"). Must not be greater than 255 characters.' example: create nullable: true - in: query name: logName description: 'Filter by log channel name. Must not be greater than 255 characters.' example: default required: false schema: type: string description: 'Filter by log channel name. Must not be greater than 255 characters.' example: default nullable: true - in: query name: subjectType description: 'Filter by affected model type (short name, e.g., "User", "Farm"). Must not be greater than 255 characters.' example: User required: false schema: type: string description: 'Filter by affected model type (short name, e.g., "User", "Farm"). Must not be greater than 255 characters.' example: User nullable: true - in: query name: causerUuid description: 'Filter by the UUID of the user who performed the action. Must be a valid UUID.' example: 550e8400-e29b-41d4-a716-446655440000 required: false schema: type: string description: 'Filter by the UUID of the user who performed the action. Must be a valid UUID.' example: 550e8400-e29b-41d4-a716-446655440000 nullable: true - in: query name: companySlug description: 'Filter by the company slug affected by the activity. The slug of an existing record in the companies table.' example: acme-corp required: false schema: type: string description: 'Filter by the company slug affected by the activity. The slug of an existing record in the companies table.' example: acme-corp nullable: true - in: query name: impersonatorUuid description: 'Filter by the UUID of the admin who was impersonating during the action. Must be a valid UUID. The uuid of an existing record in the users table.' example: 550e8400-e29b-41d4-a716-446655440000 required: false schema: type: string description: 'Filter by the UUID of the admin who was impersonating during the action. Must be a valid UUID. The uuid of an existing record in the users table.' example: 550e8400-e29b-41d4-a716-446655440000 nullable: true - in: query name: fromDate description: 'Filter activities from this date (ISO 8601 format). Must be a valid date.' example: '2026-01-01' required: false schema: type: string description: 'Filter activities from this date (ISO 8601 format). Must be a valid date.' example: '2026-01-01' nullable: true - in: query name: toDate description: 'Filter activities up to this date (ISO 8601 format). Must be a valid date. Must be a date after or equal to fromDate.' example: '2026-12-31' required: false schema: type: string description: 'Filter activities up to this date (ISO 8601 format). Must be a valid date. Must be a date after or equal to fromDate.' example: '2026-12-31' nullable: true - in: query name: batchUuid description: 'Filter by batch UUID to get related activities. Must be a valid UUID.' example: 550e8400-e29b-41d4-a716-446655440000 required: false schema: type: string description: 'Filter by batch UUID to get related activities. Must be a valid UUID.' example: 550e8400-e29b-41d4-a716-446655440000 nullable: true - in: query name: search description: 'Search in properties, description, and event fields. Must not be greater than 255 characters.' example: firmware required: false schema: type: string description: 'Search in properties, description, and event fields. Must not be greater than 255 characters.' example: firmware nullable: true - in: query name: sortBy description: 'Field to sort by (created_at, event, description, log_name).' example: created_at required: false schema: type: string description: 'Field to sort by (created_at, event, description, log_name).' example: created_at enum: - created_at - event - description - log_name nullable: true - in: query name: sortOrder description: 'Sort direction (asc, desc).' example: desc required: false schema: type: string description: 'Sort direction (asc, desc).' example: desc enum: - asc - desc nullable: true responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - 'Super Admin - Activity Logs' /api/v1/sa/activity-logs/filter-options: get: summary: 'Get available filter options for activity logs.' operationId: getAvailableFilterOptionsForActivityLogs description: "Returns distinct values for events, log names, and subject types\nto populate filter dropdowns in the UI." parameters: - in: query name: page description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 required: false schema: type: integer description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 - in: query name: perPage description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 25 required: false schema: type: integer description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 25 - in: query name: event description: 'Filter by event category (e.g., "sa.device-model-type"). Must not be greater than 255 characters.' example: sa.device-model-type required: false schema: type: string description: 'Filter by event category (e.g., "sa.device-model-type"). Must not be greater than 255 characters.' example: sa.device-model-type nullable: true - in: query name: action description: 'Filter by action type (e.g., "create", "update", "delete"). Must not be greater than 255 characters.' example: create required: false schema: type: string description: 'Filter by action type (e.g., "create", "update", "delete"). Must not be greater than 255 characters.' example: create nullable: true - in: query name: logName description: 'Filter by log channel name. Must not be greater than 255 characters.' example: default required: false schema: type: string description: 'Filter by log channel name. Must not be greater than 255 characters.' example: default nullable: true - in: query name: subjectType description: 'Filter by affected model type (short name, e.g., "User", "Farm"). Must not be greater than 255 characters.' example: User required: false schema: type: string description: 'Filter by affected model type (short name, e.g., "User", "Farm"). Must not be greater than 255 characters.' example: User nullable: true - in: query name: causerUuid description: 'Filter by the UUID of the user who performed the action. Must be a valid UUID.' example: 550e8400-e29b-41d4-a716-446655440000 required: false schema: type: string description: 'Filter by the UUID of the user who performed the action. Must be a valid UUID.' example: 550e8400-e29b-41d4-a716-446655440000 nullable: true - in: query name: companySlug description: 'Filter by the company slug affected by the activity. The slug of an existing record in the companies table.' example: acme-corp required: false schema: type: string description: 'Filter by the company slug affected by the activity. The slug of an existing record in the companies table.' example: acme-corp nullable: true - in: query name: impersonatorUuid description: 'Filter by the UUID of the admin who was impersonating during the action. Must be a valid UUID. The uuid of an existing record in the users table.' example: 550e8400-e29b-41d4-a716-446655440000 required: false schema: type: string description: 'Filter by the UUID of the admin who was impersonating during the action. Must be a valid UUID. The uuid of an existing record in the users table.' example: 550e8400-e29b-41d4-a716-446655440000 nullable: true - in: query name: fromDate description: 'Filter activities from this date (ISO 8601 format). Must be a valid date.' example: '2026-01-01' required: false schema: type: string description: 'Filter activities from this date (ISO 8601 format). Must be a valid date.' example: '2026-01-01' nullable: true - in: query name: toDate description: 'Filter activities up to this date (ISO 8601 format). Must be a valid date. Must be a date after or equal to fromDate.' example: '2026-12-31' required: false schema: type: string description: 'Filter activities up to this date (ISO 8601 format). Must be a valid date. Must be a date after or equal to fromDate.' example: '2026-12-31' nullable: true - in: query name: batchUuid description: 'Filter by batch UUID to get related activities. Must be a valid UUID.' example: 550e8400-e29b-41d4-a716-446655440000 required: false schema: type: string description: 'Filter by batch UUID to get related activities. Must be a valid UUID.' example: 550e8400-e29b-41d4-a716-446655440000 nullable: true - in: query name: search description: 'Search in properties, description, and event fields. Must not be greater than 255 characters.' example: firmware required: false schema: type: string description: 'Search in properties, description, and event fields. Must not be greater than 255 characters.' example: firmware nullable: true - in: query name: sortBy description: 'Field to sort by (created_at, event, description, log_name).' example: created_at required: false schema: type: string description: 'Field to sort by (created_at, event, description, log_name).' example: created_at enum: - created_at - event - description - log_name nullable: true - in: query name: sortOrder description: 'Sort direction (asc, desc).' example: desc required: false schema: type: string description: 'Sort direction (asc, desc).' example: desc enum: - asc - desc nullable: true responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - 'Super Admin - Activity Logs' /api/v1/sa/activity-logs/export: get: summary: 'Export activity logs.' operationId: exportActivityLogs description: "Exports activity logs with optional filtering. Supports CSV and JSON formats.\nUses streaming for memory-efficient export of large datasets." parameters: - in: query name: startDate description: 'Filter activities from this date (ISO 8601 format). Must be a valid date.' example: '2026-01-01' required: false schema: type: string description: 'Filter activities from this date (ISO 8601 format). Must be a valid date.' example: '2026-01-01' nullable: true - in: query name: endDate description: 'Filter activities up to this date (ISO 8601 format). Must be a valid date. Must be a date after or equal to startDate.' example: '2026-12-31' required: false schema: type: string description: 'Filter activities up to this date (ISO 8601 format). Must be a valid date. Must be a date after or equal to startDate.' example: '2026-12-31' nullable: true - in: query name: event description: 'Filter by event category (e.g., "sa.device-model-type"). Must not be greater than 255 characters.' example: sa.device-model-type required: false schema: type: string description: 'Filter by event category (e.g., "sa.device-model-type"). Must not be greater than 255 characters.' example: sa.device-model-type nullable: true - in: query name: action description: 'Filter by action type (e.g., "create", "update", "delete"). Must not be greater than 255 characters.' example: create required: false schema: type: string description: 'Filter by action type (e.g., "create", "update", "delete"). Must not be greater than 255 characters.' example: create nullable: true - in: query name: logName description: 'Filter by log channel name. Must not be greater than 255 characters.' example: default required: false schema: type: string description: 'Filter by log channel name. Must not be greater than 255 characters.' example: default nullable: true - in: query name: subjectType description: 'Filter by affected model type (short name, e.g., "User", "Farm"). Must not be greater than 255 characters.' example: User required: false schema: type: string description: 'Filter by affected model type (short name, e.g., "User", "Farm"). Must not be greater than 255 characters.' example: User nullable: true - in: query name: causerUuid description: 'Filter by the UUID of the user who performed the action. Must be a valid UUID.' example: 550e8400-e29b-41d4-a716-446655440000 required: false schema: type: string description: 'Filter by the UUID of the user who performed the action. Must be a valid UUID.' example: 550e8400-e29b-41d4-a716-446655440000 nullable: true - in: query name: batchUuid description: 'Filter by batch UUID to get related activities. Must be a valid UUID.' example: 550e8400-e29b-41d4-a716-446655440000 required: false schema: type: string description: 'Filter by batch UUID to get related activities. Must be a valid UUID.' example: 550e8400-e29b-41d4-a716-446655440000 nullable: true - in: query name: search description: 'Search in properties, description, and event fields. Must not be greater than 255 characters.' example: firmware required: false schema: type: string description: 'Search in properties, description, and event fields. Must not be greater than 255 characters.' example: firmware nullable: true - in: query name: format description: 'Export format: csv or json (default: json).' example: csv required: false schema: type: string description: 'Export format: csv or json (default: json).' example: csv enum: - csv - json nullable: true responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - 'Super Admin - Activity Logs' '/api/v1/sa/c/{company_slug}/users': post: summary: 'Create a new user for the specified company.' operationId: createANewUserForTheSpecifiedCompany description: '' parameters: [] responses: { } tags: - 'Super Admin - Company Users' requestBody: required: true content: application/json: schema: type: object properties: email: type: string description: "The user's email address. Must be a valid email address. Must not be greater than 100 characters." example: new.user@example.com firstName: type: string description: "The user's first name. Must be at least 2 characters. Must not be greater than 100 characters." example: John lastName: type: string description: "The user's last name. Must be at least 2 characters. Must not be greater than 100 characters." example: Doe countryIsoCode: type: string description: "The ISO code of the user's country. The iso_code of an existing record in the countries table." example: US phoneNumber: type: string description: "The user's phone number. Must be at least 6 characters." example: '+1234567890' role: type: string description: 'User role (owner, admin, or user). Defaults to user if not provided.' example: admin enum: - owner - admin - user required: - email - firstName - countryIsoCode - phoneNumber parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string '/api/v1/sa/c/{company_slug}/users/{user_uuid}': delete: summary: 'Remove a user from a specific company.' operationId: removeAUserFromASpecificCompany description: '' parameters: [] responses: { } tags: - 'Super Admin - Company Users' parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: user_uuid description: '' example: b11fab33-a56a-4a78-a3c1-b9d324c6aacd required: true schema: type: string /api/v1/sa/data-retention/audits: get: summary: 'List all data retention audit records.' operationId: listAllDataRetentionAuditRecords description: '' parameters: - in: query name: page description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 required: false schema: type: integer description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 - in: query name: perPage description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 25 required: false schema: type: integer description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 25 - in: query name: status description: 'Filter by audit status (e.g., "pending", "completed", "failed").' example: completed required: false schema: type: string description: 'Filter by audit status (e.g., "pending", "completed", "failed").' example: completed - in: query name: dataType description: 'Filter by data type (e.g., "device-messages").' example: device-messages required: false schema: type: string description: 'Filter by data type (e.g., "device-messages").' example: device-messages - in: query name: operation description: 'Filter by operation type (e.g., "delete", "archive").' example: delete required: false schema: type: string description: 'Filter by operation type (e.g., "delete", "archive").' example: delete - in: query name: startedAfter description: 'Filter audits started after this date (ISO 8601 format). Must be a valid date.' example: '2026-01-01' required: false schema: type: string description: 'Filter audits started after this date (ISO 8601 format). Must be a valid date.' example: '2026-01-01' - in: query name: startedBefore description: 'Filter audits started before this date (ISO 8601 format). Must be a valid date.' example: '2026-12-31' required: false schema: type: string description: 'Filter audits started before this date (ISO 8601 format). Must be a valid date.' example: '2026-12-31' - in: query name: sortBy description: 'Field to sort by (started_at, completed_at, created_at, data_type, operation, status, record_count).' example: started_at required: false schema: type: string description: 'Field to sort by (started_at, completed_at, created_at, data_type, operation, status, record_count).' example: started_at enum: - started_at - completed_at - created_at - data_type - operation - status - record_count nullable: true - in: query name: sortOrder description: 'Sort direction (asc, desc).' example: desc required: false schema: type: string description: 'Sort direction (asc, desc).' example: desc enum: - asc - desc nullable: true responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - 'Super Admin - Data Retention' '/api/v1/sa/data-retention/audits/{uuid}': get: summary: 'Show a single data retention audit record.' operationId: showASingleDataRetentionAuditRecord description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - 'Super Admin - Data Retention' parameters: - in: path name: uuid description: '' example: cc58b8da-c994-4cf2-a6d7-e7267b267ca2 required: true schema: type: string /api/v1/sa/data-retention/defaults: get: summary: 'List global default retention policies.' operationId: listGlobalDefaultRetentionPolicies description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - 'Super Admin - Data Retention' '/api/v1/sa/data-retention/companies/{company_slug}/policies': get: summary: 'List effective retention policies for a company.' operationId: listEffectiveRetentionPoliciesForACompany description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - 'Super Admin - Data Retention' post: summary: 'Create or update a company retention policy override.' operationId: createOrUpdateACompanyRetentionPolicyOverride description: '' parameters: [] responses: { } tags: - 'Super Admin - Data Retention' requestBody: required: true content: application/json: schema: type: object properties: dataType: type: string description: 'Data retention type slug.' example: measurement enum: - collector-measurements - device-messages - device-commands - activity-logs - automation-events - automation-executions retentionDays: type: integer description: 'Retention period in days. Must be at least 1. Must not be greater than 3650.' example: 365 archiveEnabled: type: boolean description: 'Whether expired records should be archived before deletion.' example: true required: - dataType - retentionDays parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string '/api/v1/sa/data-retention/companies/{company_slug}/policies/{dataRetentionDataType_slug}': put: summary: 'Update a company retention policy override for a specific data type.' operationId: updateACompanyRetentionPolicyOverrideForASpecificDataType description: '' parameters: [] responses: { } tags: - 'Super Admin - Data Retention' requestBody: required: true content: application/json: schema: type: object properties: retentionDays: type: integer description: 'Updated retention period in days. Must be at least 1. Must not be greater than 3650.' example: 730 archiveEnabled: type: boolean description: 'Whether archiving is enabled before deleting expired records.' example: false required: - retentionDays delete: summary: 'Delete a company retention policy override, reverting to global default.' operationId: deleteACompanyRetentionPolicyOverrideRevertingToGlobalDefault description: '' parameters: [] responses: { } tags: - 'Super Admin - Data Retention' parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: dataRetentionDataType_slug description: 'The slug of the dataRetentionDataType.' example: collector-measurements required: true schema: type: string /api/v1/sa/impersonation/stop: post: summary: 'Stop the current impersonation session.' operationId: stopTheCurrentImpersonationSession description: '' parameters: [] responses: { } tags: - 'Super Admin - Impersonation' /api/v1/sa/impersonation/status: get: summary: 'Get current impersonation status.' operationId: getCurrentImpersonationStatus description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - 'Super Admin - Impersonation' /api/v1/sa/impersonation/start: post: summary: 'Start an impersonation session.' operationId: startAnImpersonationSession description: '' parameters: [] responses: { } tags: - 'Super Admin - Impersonation' /api/v1/sa/impersonation/sessions: get: summary: 'List active impersonation sessions.' operationId: listActiveImpersonationSessions description: '' parameters: - in: query name: page description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 required: false schema: type: integer description: 'Page number for pagination (minimum: 1). Must be at least 1.' example: 1 - in: query name: perPage description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 25 required: false schema: type: integer description: 'Number of items per page (1-100). Must be at least 1. Must not be greater than 100.' example: 25 - in: query name: impersonatorUuid description: 'Filter by impersonator user UUID. Must be a valid UUID.' example: 550e8400-e29b-41d4-a716-446655440000 required: false schema: type: string description: 'Filter by impersonator user UUID. Must be a valid UUID.' example: 550e8400-e29b-41d4-a716-446655440000 nullable: true - in: query name: targetUserUuid description: 'Filter by target user UUID. Must be a valid UUID.' example: 550e8400-e29b-41d4-a716-446655440000 required: false schema: type: string description: 'Filter by target user UUID. Must be a valid UUID.' example: 550e8400-e29b-41d4-a716-446655440000 nullable: true - in: query name: active description: 'Filter by active sessions (default true).' example: true required: false schema: type: boolean description: 'Filter by active sessions (default true).' example: true - in: query name: fromDate description: 'Filter sessions starting on/after this date (ISO 8601). Must be a valid date.' example: '2026-01-01' required: false schema: type: string description: 'Filter sessions starting on/after this date (ISO 8601). Must be a valid date.' example: '2026-01-01' nullable: true - in: query name: toDate description: 'Filter sessions starting on/before this date (ISO 8601). Must be a valid date. Must be a date after or equal to fromDate.' example: '2026-12-31' required: false schema: type: string description: 'Filter sessions starting on/before this date (ISO 8601). Must be a valid date. Must be a date after or equal to fromDate.' example: '2026-12-31' nullable: true - in: query name: sortBy description: 'Sort field (startedAt, expiresAt, createdAt).' example: startedAt required: false schema: type: string description: 'Sort field (startedAt, expiresAt, createdAt).' example: startedAt enum: - startedAt - expiresAt - createdAt nullable: true - in: query name: sortOrder description: 'Sort direction (asc, desc).' example: desc required: false schema: type: string description: 'Sort direction (asc, desc).' example: desc enum: - asc - desc nullable: true responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - 'Super Admin - Impersonation' '/api/v1/sa/impersonation/sessions/{session_uuid}/terminate': post: summary: 'Terminate an impersonation session (admin override).' operationId: terminateAnImpersonationSessionadminOverride description: '' parameters: [] responses: { } tags: - 'Super Admin - Impersonation' parameters: - in: path name: session_uuid description: '' example: 5eee9f6f-18ce-35ad-a991-6d2824df0fd3 required: true schema: type: string '/api/v1/sa/tracklab/users/{user_uuid}/elevate': post: summary: 'Elevate a TrackLab user to super admin status.' operationId: elevateATrackLabUserToSuperAdminStatus description: '' parameters: [] responses: { } tags: - 'Super Admin - TrackLab Users' parameters: - in: path name: user_uuid description: '' example: b11fab33-a56a-4a78-a3c1-b9d324c6aacd required: true schema: type: string '/api/v1/sa/tracklab/users/{user_uuid}/revoke': post: summary: 'Revoke super admin status from a TrackLab user.' operationId: revokeSuperAdminStatusFromATrackLabUser description: '' parameters: [] responses: { } tags: - 'Super Admin - TrackLab Users' parameters: - in: path name: user_uuid description: '' example: b11fab33-a56a-4a78-a3c1-b9d324c6aacd required: true schema: type: string /api/v1/sa/users: get: summary: '' operationId: getApiV1SaUsers description: '' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: - uuid: b11fab33-a56a-4a78-a3c1-b9d324c6aacd createdAt: '2025-11-12T20:27:08+00:00' updatedAt: '2026-02-10T15:20:26+00:00' defaultCompanySlug: null emailVerifiedAt: null defaultCountryIsoCode: '' defaultCountryEmoji: '' email: liquid.ideas@gmail.com firstName: Jo lastName: Whitehouse phoneNumbers: [] roles: [] imgUrl: null imgThumbUrl: null imgLargeUrl: null imgUrlExpiresAt: null isActive: true disabledAt: null status: null statusName: null - uuid: b11fab33-a56a-4a78-a3c1-b9d324c6aacd createdAt: '2025-11-12T20:27:08+00:00' updatedAt: '2026-02-10T15:20:26+00:00' defaultCompanySlug: null emailVerifiedAt: null defaultCountryIsoCode: '' defaultCountryEmoji: '' email: liquid.ideas@gmail.com firstName: Jo lastName: Whitehouse phoneNumbers: [] roles: [] imgUrl: null imgThumbUrl: null imgLargeUrl: null imgUrlExpiresAt: null isActive: true disabledAt: null status: null statusName: null properties: data: type: array example: - uuid: b11fab33-a56a-4a78-a3c1-b9d324c6aacd createdAt: '2025-11-12T20:27:08+00:00' updatedAt: '2026-02-10T15:20:26+00:00' defaultCompanySlug: null emailVerifiedAt: null defaultCountryIsoCode: '' defaultCountryEmoji: '' email: liquid.ideas@gmail.com firstName: Jo lastName: Whitehouse phoneNumbers: [] roles: [] imgUrl: null imgThumbUrl: null imgLargeUrl: null imgUrlExpiresAt: null isActive: true disabledAt: null status: null statusName: null - uuid: b11fab33-a56a-4a78-a3c1-b9d324c6aacd createdAt: '2025-11-12T20:27:08+00:00' updatedAt: '2026-02-10T15:20:26+00:00' defaultCompanySlug: null emailVerifiedAt: null defaultCountryIsoCode: '' defaultCountryEmoji: '' email: liquid.ideas@gmail.com firstName: Jo lastName: Whitehouse phoneNumbers: [] roles: [] imgUrl: null imgThumbUrl: null imgLargeUrl: null imgUrlExpiresAt: null isActive: true disabledAt: null status: null statusName: null items: type: object properties: uuid: type: string example: b11fab33-a56a-4a78-a3c1-b9d324c6aacd createdAt: type: string example: '2025-11-12T20:27:08+00:00' updatedAt: type: string example: '2026-02-10T15:20:26+00:00' defaultCompanySlug: type: string example: null nullable: true emailVerifiedAt: type: string example: null nullable: true defaultCountryIsoCode: type: string example: '' defaultCountryEmoji: type: string example: '' email: type: string example: liquid.ideas@gmail.com firstName: type: string example: Jo lastName: type: string example: Whitehouse phoneNumbers: type: array example: [] roles: type: array example: [] imgUrl: type: string example: null nullable: true imgThumbUrl: type: string example: null nullable: true imgLargeUrl: type: string example: null nullable: true imgUrlExpiresAt: type: string example: null nullable: true isActive: type: boolean example: true disabledAt: type: string example: null nullable: true status: type: string example: null nullable: true statusName: type: string example: null nullable: true tags: - 'Super Admin - Users' requestBody: required: false content: application/json: schema: type: object properties: search: type: string description: 'Optional search term for name or email. Must not be greater than 255 characters.' example: tim companySlug: type: string description: 'Optional company slug to scope results. The slug of an existing record in the companies table.' example: tracklab-solar role: type: string description: 'Optional role filter.' example: admin enum: - admin - owner - user - tracklab-admin - tracklab-support - tracklab-readonly - manager - technician - viewer - external-supplier - external-support - tracklab-dev isActive: type: string description: 'Optional active filter (0/1/true/false).' example: true enum: - '0' - '1' - 'true' - 'false' page: type: integer description: 'Pagination page number. Must be at least 1.' example: 1 perPage: type: integer description: 'Pagination size. Must be at least 1. Must not be greater than 100.' example: 25 '/api/v1/sa/users/{uuid}': get: summary: '' operationId: getApiV1SaUsersUuid description: '' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: uuid: b11fab33-a56a-4a78-a3c1-b9d324c6aacd createdAt: '2025-11-12T20:27:08+00:00' updatedAt: '2026-02-10T15:20:26+00:00' defaultCompanySlug: null emailVerifiedAt: null defaultCountryIsoCode: '' defaultCountryEmoji: '' email: liquid.ideas@gmail.com firstName: Jo lastName: Whitehouse phoneNumbers: [] roles: [] imgUrl: null imgThumbUrl: null imgLargeUrl: null imgUrlExpiresAt: null isActive: true disabledAt: null status: null statusName: null properties: data: type: object properties: uuid: type: string example: b11fab33-a56a-4a78-a3c1-b9d324c6aacd createdAt: type: string example: '2025-11-12T20:27:08+00:00' updatedAt: type: string example: '2026-02-10T15:20:26+00:00' defaultCompanySlug: type: string example: null nullable: true emailVerifiedAt: type: string example: null nullable: true defaultCountryIsoCode: type: string example: '' defaultCountryEmoji: type: string example: '' email: type: string example: liquid.ideas@gmail.com firstName: type: string example: Jo lastName: type: string example: Whitehouse phoneNumbers: type: array example: [] roles: type: array example: [] imgUrl: type: string example: null nullable: true imgThumbUrl: type: string example: null nullable: true imgLargeUrl: type: string example: null nullable: true imgUrlExpiresAt: type: string example: null nullable: true isActive: type: boolean example: true disabledAt: type: string example: null nullable: true status: type: string example: null nullable: true statusName: type: string example: null nullable: true tags: - 'Super Admin - Users' patch: summary: '' operationId: patchApiV1SaUsersUuid description: '' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: uuid: b11fab33-a56a-4a78-a3c1-b9d324c6aacd createdAt: '2025-11-12T20:27:08+00:00' updatedAt: '2026-02-10T15:20:26+00:00' defaultCompanySlug: null emailVerifiedAt: null defaultCountryIsoCode: '' defaultCountryEmoji: '' email: liquid.ideas@gmail.com firstName: Jo lastName: Whitehouse phoneNumbers: [] roles: [] imgUrl: null imgThumbUrl: null imgLargeUrl: null imgUrlExpiresAt: null isActive: true disabledAt: null status: null statusName: null properties: data: type: object properties: uuid: type: string example: b11fab33-a56a-4a78-a3c1-b9d324c6aacd createdAt: type: string example: '2025-11-12T20:27:08+00:00' updatedAt: type: string example: '2026-02-10T15:20:26+00:00' defaultCompanySlug: type: string example: null nullable: true emailVerifiedAt: type: string example: null nullable: true defaultCountryIsoCode: type: string example: '' defaultCountryEmoji: type: string example: '' email: type: string example: liquid.ideas@gmail.com firstName: type: string example: Jo lastName: type: string example: Whitehouse phoneNumbers: type: array example: [] roles: type: array example: [] imgUrl: type: string example: null nullable: true imgThumbUrl: type: string example: null nullable: true imgLargeUrl: type: string example: null nullable: true imgUrlExpiresAt: type: string example: null nullable: true isActive: type: boolean example: true disabledAt: type: string example: null nullable: true status: type: string example: null nullable: true statusName: type: string example: null nullable: true tags: - 'Super Admin - Users' requestBody: required: false content: application/json: schema: type: object properties: email: type: string description: 'Updated user email address. Must be a valid email address. Must not be greater than 100 characters.' example: updated.user@example.com firstName: type: string description: 'Updated first name. Must be at least 2 characters. Must not be greater than 100 characters.' example: Tim lastName: type: string description: 'Updated last name. Must be at least 2 characters. Must not be greater than 100 characters.' example: Haak countryIsoCode: type: string description: 'ISO country code. The iso_code of an existing record in the countries table.' example: NL phoneNumber: type: string description: 'Updated phone number. Must be at least 6 characters.' example: '+31612345678' delete: summary: '' operationId: deleteApiV1SaUsersUuid description: '' parameters: [] responses: { } tags: - 'Super Admin - Users' parameters: - in: path name: uuid description: '' example: b11fab33-a56a-4a78-a3c1-b9d324c6aacd required: true schema: type: string '/api/v1/sa/users/{user_uuid}/role': get: summary: '' operationId: getApiV1SaUsersUser_uuidRole description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - 'Super Admin - Users' parameters: - in: path name: user_uuid description: '' example: b11fab33-a56a-4a78-a3c1-b9d324c6aacd required: true schema: type: string '/api/v1/sa/users/{user_uuid}/permissions': get: summary: '' operationId: getApiV1SaUsersUser_uuidPermissions description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - 'Super Admin - Users' parameters: - in: path name: user_uuid description: '' example: b11fab33-a56a-4a78-a3c1-b9d324c6aacd required: true schema: type: string '/api/v1/sa/users/{user_uuid}/profile/picture': post: summary: '' operationId: postApiV1SaUsersUser_uuidProfilePicture description: '' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: uuid: b11fab33-a56a-4a78-a3c1-b9d324c6aacd createdAt: '2025-11-12T20:27:08+00:00' updatedAt: '2026-02-10T15:20:26+00:00' defaultCompanySlug: null emailVerifiedAt: null defaultCountryIsoCode: '' defaultCountryEmoji: '' email: liquid.ideas@gmail.com firstName: Jo lastName: Whitehouse phoneNumbers: [] roles: [] imgUrl: null imgThumbUrl: null imgLargeUrl: null imgUrlExpiresAt: null isActive: true disabledAt: null status: null statusName: null properties: data: type: object properties: uuid: type: string example: b11fab33-a56a-4a78-a3c1-b9d324c6aacd createdAt: type: string example: '2025-11-12T20:27:08+00:00' updatedAt: type: string example: '2026-02-10T15:20:26+00:00' defaultCompanySlug: type: string example: null nullable: true emailVerifiedAt: type: string example: null nullable: true defaultCountryIsoCode: type: string example: '' defaultCountryEmoji: type: string example: '' email: type: string example: liquid.ideas@gmail.com firstName: type: string example: Jo lastName: type: string example: Whitehouse phoneNumbers: type: array example: [] roles: type: array example: [] imgUrl: type: string example: null nullable: true imgThumbUrl: type: string example: null nullable: true imgLargeUrl: type: string example: null nullable: true imgUrlExpiresAt: type: string example: null nullable: true isActive: type: boolean example: true disabledAt: type: string example: null nullable: true status: type: string example: null nullable: true statusName: type: string example: null nullable: true tags: - 'Super Admin - Users' requestBody: required: true content: application/json: schema: type: object properties: file: type: string description: '' example: perferendis required: - file parameters: - in: path name: user_uuid description: '' example: b11fab33-a56a-4a78-a3c1-b9d324c6aacd required: true schema: type: string '/api/v1/sa/users/{user_uuid}/profile/picture/{format}': get: summary: '' operationId: getApiV1SaUsersUser_uuidProfilePictureFormat description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - 'Super Admin - Users' parameters: - in: path name: user_uuid description: '' example: b11fab33-a56a-4a78-a3c1-b9d324c6aacd required: true schema: type: string - in: path name: format description: 'Optional parameter.' required: true schema: type: string examples: omitted: summary: 'When the value is omitted' value: '' present: summary: 'When the value is present' value: architecto /api/v1/sa/c: get: summary: 'List all companies' operationId: listAllCompanies description: 'Returns a paginated list of all companies with optional filtering.' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - 'Super Admin > Companies' requestBody: required: false content: application/json: schema: type: object properties: search: type: string description: 'Search term for filtering companies. Must not be greater than 100 characters.' example: Solar enabled: type: boolean description: 'Filter by enabled status.' example: true perPage: type: integer description: 'Number of records per page (1-100). Must be at least 1. Must not be greater than 100.' example: 25 page: type: integer description: 'Page number for pagination. Must be at least 1.' example: 1 post: summary: 'Create a new company' operationId: createANewCompany description: 'Creates a new company with the provided details.' parameters: [] responses: { } tags: - 'Super Admin > Companies' requestBody: required: true content: application/json: schema: type: object properties: name: type: string description: 'Company name. Must be at least 2 characters. Must not be greater than 255 characters.' example: 'Solar Energy Corp' slug: type: string description: 'URL-friendly identifier (lowercase letters, numbers, and hyphens). Must match the regex /^[a-z0-9-]+$/. Must be at least 2 characters. Must not be greater than 100 characters.' example: solar-energy-corp countryIsoCode: type: string description: 'ISO country code. The iso_code of an existing record in the countries table.' example: US required: - name - countryIsoCode '/api/v1/sa/c/{company_slug}': get: summary: 'Get a company' operationId: getACompany description: 'Returns the details of a specific company.' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - 'Super Admin > Companies' requestBody: required: false content: application/json: schema: type: object properties: search: type: string description: 'Search term for filtering companies. Must not be greater than 100 characters.' example: Solar enabled: type: boolean description: 'Filter by enabled status.' example: true perPage: type: integer description: 'Number of records per page (1-100). Must be at least 1. Must not be greater than 100.' example: 25 page: type: integer description: 'Page number for pagination. Must be at least 1.' example: 1 patch: summary: 'Update a company' operationId: updateACompany description: 'Updates the specified company with the provided details.' parameters: [] responses: { } tags: - 'Super Admin > Companies' requestBody: required: false content: application/json: schema: type: object properties: name: type: string description: 'Company name. Must be at least 2 characters. Must not be greater than 255 characters.' example: 'Solar Energy Corp Updated' slug: type: string description: 'URL-friendly identifier (lowercase letters, numbers, and hyphens). Must match the regex /^[a-z0-9-]+$/. Must be at least 2 characters. Must not be greater than 100 characters.' example: solar-energy-corp-updated countryIsoCode: type: string description: 'ISO country code. The iso_code of an existing record in the countries table.' example: US enabled: type: boolean description: 'Whether the company is enabled.' example: true delete: summary: 'Delete a company' operationId: deleteACompany description: 'Soft deletes the specified company.' parameters: [] responses: { } tags: - 'Super Admin > Companies' parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string '/api/v1/sa/c/{company_slug}/disable': patch: summary: 'Disable a company' operationId: disableACompany description: 'Disables the specified company. Users of this company will not be able to log in.' parameters: [] responses: { } tags: - 'Super Admin > Companies' parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string '/api/v1/sa/c/{company_slug}/enable': patch: summary: 'Enable a company' operationId: enableACompany description: 'Enables the specified company. Users of this company will be able to log in again.' parameters: [] responses: { } tags: - 'Super Admin > Companies' parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string '/api/v1/sa/c/{company_slug}/address': post: summary: '' operationId: postApiV1SaCCompany_slugAddress description: '' parameters: [] responses: { } tags: - 'Super Admin > Companies' requestBody: required: true content: application/json: schema: type: object properties: addressString: type: string description: 'Full address as a single string. If provided, individual address fields are not required. Must not be greater than 500 characters.' example: '123 Main St, London SW1A 1AA' addressLine1: type: string description: 'First line of the address (required if addressString not provided). Must not be greater than 255 characters.' example: '123 Main Street' city: type: string description: 'City name (required if addressString not provided). Must not be greater than 255 characters.' example: London postCode: type: string description: 'Postal code (required if addressString not provided). Must not be greater than 20 characters.' example: 'SW1A 1AA' countryIsoCode: type: string description: 'Two-letter ISO country code. The iso_code of an existing record in the countries table.' example: GB addressLine2: type: string description: 'Second line of the address. Must not be greater than 255 characters.' example: 'Apt 4B' nullable: true neighborhood: type: string description: 'Neighborhood name. Must not be greater than 255 characters.' example: Westminster nullable: true locality: type: string description: 'Locality name. Must not be greater than 255 characters.' example: 'Central London' nullable: true place: type: string description: 'Place name. Must not be greater than 255 characters.' example: 'Piccadilly Circus' nullable: true district: type: string description: 'District name. Must not be greater than 255 characters.' example: 'City of Westminster' nullable: true region: type: string description: 'Region name. Must not be greater than 255 characters.' example: 'Greater London' nullable: true location: type: object description: 'Geographic coordinates (supports both latitude/longitude and lat/long formats).' example: lat: 51.5074 long: -0.1278 properties: latitude: type: number description: 'Latitude coordinate (required if location object is provided). This field is required when location is present.' example: 51.5074 longitude: type: number description: 'Longitude coordinate (required if location object is provided). This field is required when location is present.' example: -0.1278 nullable: true required: - addressLine1 - city - postCode - countryIsoCode parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string '/api/v1/sa/c/{company_slug}/logo': post: summary: "Upload or replace a company's logo." operationId: uploadOrReplaceACompanysLogo description: '' parameters: [] responses: { } tags: - 'Super Admin > Companies' requestBody: required: true content: multipart/form-data: schema: type: object properties: file: type: string format: binary description: 'Must be an image.' required: - file delete: summary: "Delete a company's logo." operationId: deleteACompanysLogo description: '' parameters: [] responses: { } tags: - 'Super Admin > Companies' parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string '/api/v1/sa/c/{company_slug}/logo/{format}': get: summary: "Get a company's logo in the requested format." operationId: getACompanysLogoInTheRequestedFormat description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - 'Super Admin > Companies' parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: format description: 'Optional parameter.' required: true schema: type: string examples: omitted: summary: 'When the value is omitted' value: '' present: summary: 'When the value is present' value: recusandae '/api/v1/sa/c/{company_slug}/logo/{signedToken}/{format}/image.webp': get: summary: "Get a company's logo using a signed URL token." operationId: getACompanysLogoUsingASignedURLToken description: "The token contains encrypted company slug and expiry timestamp.\nURL format: /sa/c/{companySlug}/logo/{signedToken}/{format}/image.webp" parameters: [] responses: 200: description: '' content: text/plain: schema: type: string example: 'The image file stream' 403: description: '' content: application/json: schema: type: object example: message: 'Invalid or expired token.' properties: message: type: string example: 'Invalid or expired token.' 404: description: '' content: application/json: schema: type: object example: message: 'Company not found.' properties: message: type: string example: 'Company not found.' tags: - 'Super Admin > Companies' parameters: - in: path name: company_slug description: 'The slug of the company.' example: tracklab required: true schema: type: string - in: path name: signedToken description: 'The encrypted signed token.' example: eyJpdiI6... required: true schema: type: string - in: path name: format description: 'The image format/conversion name.' example: square-256-webp required: true schema: type: string - in: path name: company description: 'The company slug.' example: demo-gui required: true schema: type: string /api/v1/sa/mobile/audit-events: get: summary: 'List mobile audit events' operationId: listMobileAuditEvents description: 'Returns a paginated list of all mobile audit events with optional filtering.' parameters: - in: query name: page description: 'Page number for pagination. Must be at least 1.' example: 1 required: false schema: type: integer description: 'Page number for pagination. Must be at least 1.' example: 1 - in: query name: perPage description: 'Number of audit events to return per page (1-100). Must be at least 1. Must not be greater than 100.' example: 25 required: false schema: type: integer description: 'Number of audit events to return per page (1-100). Must be at least 1. Must not be greater than 100.' example: 25 - in: query name: companySlug description: 'Filter audit events to a single company slug. The slug of an existing record in the companies table.' example: acme-corp required: false schema: type: string description: 'Filter audit events to a single company slug. The slug of an existing record in the companies table.' example: acme-corp nullable: true - in: query name: collectorUuid description: 'Filter audit events to a single collector UUID. Must be a valid UUID. The uuid of an existing record in the collectors table.' example: 550e8400-e29b-41d4-a716-446655440010 required: false schema: type: string description: 'Filter audit events to a single collector UUID. Must be a valid UUID. The uuid of an existing record in the collectors table.' example: 550e8400-e29b-41d4-a716-446655440010 nullable: true - in: query name: userUuid description: 'Filter audit events to a single user UUID. Must be a valid UUID. The uuid of an existing record in the users table.' example: 550e8400-e29b-41d4-a716-446655440011 required: false schema: type: string description: 'Filter audit events to a single user UUID. Must be a valid UUID. The uuid of an existing record in the users table.' example: 550e8400-e29b-41d4-a716-446655440011 nullable: true - in: query name: eventName description: 'Filter by mobile audit event type slug. The slug of an existing record in the mobile_audit_event_types table.' example: mobile-ncu required: false schema: type: string description: 'Filter by mobile audit event type slug. The slug of an existing record in the mobile_audit_event_types table.' example: mobile-ncu nullable: true - in: query name: actionName description: 'Filter by mobile audit action type slug. The slug of an existing record in the mobile_audit_action_types table.' example: command-send required: false schema: type: string description: 'Filter by mobile audit action type slug. The slug of an existing record in the mobile_audit_action_types table.' example: command-send nullable: true - in: query name: dateFrom description: 'Only include audit events that occurred on or after this ISO 8601 timestamp. Must be a valid date.' example: '2026-03-01T00:00:00Z' required: false schema: type: string description: 'Only include audit events that occurred on or after this ISO 8601 timestamp. Must be a valid date.' example: '2026-03-01T00:00:00Z' nullable: true - in: query name: dateTo description: 'Only include audit events that occurred on or before this ISO 8601 timestamp. Must be a valid date. Must be a date after or equal to dateFrom.' example: '2026-03-11T23:59:59Z' required: false schema: type: string description: 'Only include audit events that occurred on or before this ISO 8601 timestamp. Must be a valid date. Must be a date after or equal to dateFrom.' example: '2026-03-11T23:59:59Z' nullable: true responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - 'Super Admin > Mobile Audit Events' '/api/v1/sa/mobile/audit-events/{auditEvent_uuid}': get: summary: 'Show a mobile audit event' operationId: showAMobileAuditEvent description: 'Returns full detail for a single mobile audit event including context, request, result, operator label, and device info.' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - 'Super Admin > Mobile Audit Events' parameters: - in: path name: auditEvent_uuid description: '' example: de47c505-d218-3e81-89cb-159c6185fa5e required: true schema: type: string /api/v1/sa/mobile/devices: get: summary: 'List mobile devices' operationId: listMobileDevices description: 'Returns a paginated list of all mobile devices with optional filtering.' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - 'Super Admin > Mobile Devices' '/api/v1/sa/mobile/devices/{uuid}': get: summary: 'Show a mobile device' operationId: showAMobileDevice description: 'Returns detailed information for a single mobile device including masked push token and audit event count.' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - 'Super Admin > Mobile Devices' parameters: - in: path name: uuid description: '' example: 91a2dba3-a2bd-4b91-bbe9-fa27c2970489 required: true schema: type: string /api/v1/sa/admin/routes: get: summary: '' operationId: getApiV1SaAdminRoutes description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - 'Super Admin > Routes' requestBody: required: false content: application/json: schema: type: object properties: all: type: boolean description: 'Include all registered routes (not just the API prefix).' example: false /api/v1/test/basic_system: get: summary: 'Test System' operationId: testSystem description: 'Check if the system is working properly. Tests DB + Redis connectivity.' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: success: true data: systemWorking: true services: database: true redis: true errors: [] properties: success: type: boolean example: true data: type: object properties: systemWorking: type: boolean example: true services: type: object properties: database: type: boolean example: true redis: type: boolean example: true errors: type: array example: [] tags: - System security: []