components: responses: {} schemas: EmptyResponse: description: Consumer of this response should look for a http status code to comprehend the response example: '' title: EmptyResponse type: string Incident: description: Incident model example: detected_at: '2021-06-21T18:28:00.717720Z' id: 3a9c7416-ff53-48d1-b667-99e822eec29b open: false possible_actions: - reopen severity: high signal_id: 3a9c7416-ff53-48d1-b667-99e822ee0010 sonic_id: 3a9c7416-ff53-48d1-b667-99e822ee0011 state: resolved type: long_flow_alert properties: detected_at: description: The timestamp when the incident occurred. type: string id: description: Incident UUID type: string open: description: Whether the incident is opened or closed type: boolean possible_actions: description: List of available actions for the incident items: $ref: '#/components/schemas/IncidentPossibleActions' type: array severity: description: Severity of the incident enum: - low - high type: string signal_id: description: Signal UUID type: string sonic_id: description: Sonic UUID type: string state: description: State of the incident enum: - initialising - contacting - waiting_for_user - snoozed - resolved - dismissed - processing - contacted - escalation_ended type: string type: description: Incident type enum: - high_volume_alert - long_flow_alert - device_handle_moved - battery_too_low_to_move_handle - radio_disconnection - cloud_disconnection - pressure_test_failed - pressure_test_skipped - pressure_test_aborted - health_check_failed - low_battery_level - legionella_risk - legionella_high_risk - low_water_temperature - water_presence_detected - low_temperature - high_temperature - high_humidity - advanced_valve_misalignment - backup_battery_usage type: string title: Incident type: object IncidentAction: properties: action: description: An action transitioning the incident to another state e.g. resolved. type: string title: IncidentAction type: object IncidentPaginatedResponse: description: Response for multiple incidents example: data: - detected_at: '2021-06-21T18:28:00.717720Z' id: 3a9c7416-ff53-48d1-b667-99e822eec29b open: false possible_actions: - reopen severity: high signal_id: 3a9c7416-ff53-48d1-b667-99e822ee0010 sonic_id: 3a9c7416-ff53-48d1-b667-99e822ee0011 state: resolved type: long_flow_alert page_number: 1 page_size: 10 total_entries: 10 total_pages: 2 properties: data: items: $ref: '#/components/schemas/Incident' type: array page_number: type: number page_size: type: number total_entries: type: number total_pages: type: number title: IncidentPaginatedResponse type: object IncidentPossibleActions: title: IncidentPossibleActions type: string JsonErrorResponse: properties: errors: items: properties: detail: example: null value where string expected type: string source: properties: pointer: example: /data/attributes/petName type: string required: - pointer type: object title: example: Invalid value type: string required: - title - source - detail type: object type: array required: - errors title: JsonErrorResponse type: object NotificationSettings: description: Notification settings data example: battery_too_low_to_move_handle: true cloud_disconnection: true device_handle_moved: true health_check_failed: true high_humidity: true high_humidity_threshold: true high_temperature: true high_temperature_threshold: true high_volume_threshold_litres: 200 legionella_risk: true long_flow_notification_delay_mins: 60 low_battery_level: true low_temperature: true low_temperature_threshold: true low_water_temperature: true pressure_test_failed: true pressure_test_skipped: true radio_disconnection: true water_presence_detected: true properties: battery_too_low_to_move_handle: description: Handle couldn't be moved due to low battery notification type: boolean cloud_disconnection: description: Cloud disconnection notification (e.g. internet failure) type: boolean device_handle_moved: description: Handle moved notification (e.g. manually closing the valve) type: boolean health_check_failed: description: Health check failed notification type: boolean high_humidity: description: High humidity notification type: boolean high_humidity_threshold: description: High humidity notification threshold type: boolean high_temperature: description: High temperature notification type: boolean high_temperature_threshold: description: High temperature notification threshold type: boolean high_volume_threshold_litres: description: Send a notification when we identify water is constantly running and the volume is more than X liters. type: integer legionella_risk: description: Legionella stagnation and temperature checks will made every day if true type: boolean long_flow_notification_delay_mins: description: Send a notification when we identify water is constantly running for over than X mins. type: integer low_battery_level: description: Low battery notification type: boolean low_temperature: description: Low temperature notification type: boolean low_temperature_threshold: description: Low temperature notification threshold type: boolean low_water_temperature: description: Low water temperature notification type: boolean pressure_test_failed: description: Pressure test failed notification type: boolean pressure_test_skipped: description: Pressure test skipped notification type: boolean radio_disconnection: description: Radio disconnection notification (e.g. Sonic cannot connect to Bridge) type: boolean water_presence_detected: description: Water presence detected notification type: boolean title: NotificationSettings type: object PropertiesPaginatedResponse: description: Response for multiple properties example: data: - active: true address: Kensington Gardens city: London country: United Kingdom created_at: '2022-01-22T10:20:30.000Z' id: 7bcb5fe0-abcd-25e7-93c5-6e6a71c123d2 lat: 51.5158392 lng: -0.1114453 name: Kensington Gardens postcode: W8 4PX uprn: '' page_number: 1 page_size: 10 total_entries: 10 total_pages: 2 properties: data: items: $ref: '#/components/schemas/Property' type: array page_number: type: number page_size: type: number total_entries: type: number total_pages: type: number title: PropertiesPaginatedResponse type: object Property: allOf: - $ref: '#/components/schemas/PropertyUpdate' description: Property model example: active: true address: Kensington Gardens city: London country: United Kingdom created_at: '2022-01-22T10:20:30.000Z' id: 7bcb5fe0-abcd-25e7-93c5-6e6a71c123d2 lat: 51.5158392 lng: -0.1114453 name: Kensington Gardens postcode: W8 4PX uprn: '' properties: id: description: Property ID type: string title: Property type: object PropertySettings: description: Property settings data example: auto_shut_off: true pressure_tests_enabled: true pressure_tests_schedule: 03:00:00 timezone: Europe/London webhook_enabled: true webhook_url: https://api.acme.com/webhooks properties: auto_shut_off: description: Automatic shut off type: boolean pressure_tests_enabled: description: Enable or disable the pressure test type: boolean pressure_tests_schedule: description: The time of day when the pressure test runs, formatted as HH:MM:SS in a 24-hour clock. in 24h clock. type: string timezone: description: The time zone of the property. type: string webhook_enabled: description: Enable or disable the webhook type: boolean webhook_url: description: Webhook url type: string title: PropertySettings type: object PropertyUpdate: example: active: true address: Kensington Gardens city: London country: United Kingdom created_at: '2022-01-22T10:20:30.000Z' lat: 51.5158392 lng: -0.1114453 name: Kensington Gardens postcode: W8 4PX uprn: '' properties: active: description: Whether the property is active or not type: boolean address: description: Property address type: string city: description: Property city type: string country: description: Property country type: string created_at: description: Date when the property has been created. type: string lat: description: Property latitude type: number lng: description: Property longitude type: number name: description: Property name type: string postcode: description: Property postcode type: string uprn: description: Property uprn type: string title: PropertyUpdate type: object Signal: description: Signal model example: boot_time: 1622972033 cloud_connection: connected created_at: '2022-01-22T10:20:30.000Z' id: 7bcb5fe0-a28a-25e7-93c5-6e6a71c123d2 modem_boot_time: 1623526880 modem_version: 1.2.535-84ea330 name: This is my Signal name serial_no: fd3c164c13b2d20e version: 1.2.547-c8efc17 wifi_rssi: -69 properties: boot_time: description: Signal boot time timestamp type: number cloud_connection: description: Cloud connection status enum: - connected - disconnected type: string created_at: description: The date when the Signal was registered. type: string id: description: Signal UUID type: string modem_boot_time: description: Modem boot time timestamp type: number modem_version: description: Modem Signal Version type: string name: description: Signal name type: string serial_no: description: Signal Serial Number type: string version: description: Signal Version type: string wifi_rssi: description: Wi-Fi RSSI (Received Signal Strength Indicator). type: integer title: Signal type: object SignalsPaginatedResponse: description: Response for multiple Signals example: data: - boot_time: 1622972033 cloud_connection: connected created_at: '2022-01-22T10:20:30.000Z' id: 7bcb5fe0-a28a-25e7-93c5-6e6a71c123d2 modem_boot_time: 1623526880 modem_version: 1.2.535-84ea330 name: This is my Signal name serial_no: fd3c164c13b2d20e version: 1.2.547-c8efc17 wifi_rssi: -69 page_number: 1 page_size: 10 total_entries: 10 total_pages: 2 properties: data: items: $ref: '#/components/schemas/Signal' type: array page_number: type: number page_size: type: number total_entries: type: number total_pages: type: number title: SignalsPaginatedResponse type: object Sonic: description: Sonic model example: battery: external_power_supply created_at: '2022-01-22T10:20:30.000Z' id: 39bdc4af-a1b8-47d4-8342-82d311e5538e name: This is my Sonic name radio_connection: connected radio_rssi: 166 serial_no: 20fa74b6bffabc12 signal_id: 39bdc4af-a1b8-47d4-8342-82d311e1234e status: active valve_state: open properties: battery: description: The current battery level of the Sonic device. enum: - external_power_supply - high - mid - low type: string created_at: description: Date when the Sonic has been registered. type: string id: description: Sonic UUID type: string name: description: Sonic name type: string radio_connection: description: The status of the radio connection. enum: - connected - disconnected type: string radio_rssi: description: 'Radio rssi with values: < 60 no connection, 100 - 120 good, > 120 very good' type: integer serial_no: description: Serial Number type: string signal_id: description: Signal UUID type: string status: description: Sonic status type: string valve_state: description: Valve state enum: - open - closed - opening - closing - faulty - pressure_test - requested_open - requested_closed type: string title: Sonic type: object SonicPaginatedResponse: description: Response for multiple Sonics example: data: - battery: external_power_supply created_at: '2022-01-22T10:20:30.000Z' id: 39bdc4af-a1b8-47d4-8342-82d311e5538e name: This is my Sonic name radio_connection: connected radio_rssi: 166 serial_no: 20fa74b6bffabc12 signal_id: 39bdc4af-a1b8-47d4-8342-82d311e1234e status: active valve_state: open page_number: 1 page_size: 10 total_entries: 10 total_pages: 2 properties: data: items: $ref: '#/components/schemas/Sonic' type: array page_number: type: number page_size: type: number total_entries: type: number total_pages: type: number title: SonicPaginatedResponse type: object SonicUpdateRequest: properties: name: description: Sonic name type: string title: SonicUpdateRequest type: object SonicUpdateValveRequest: properties: action: description: Action for opening or closing the valve. enum: - open - close type: string required: - action title: SonicUpdateValveRequest type: object Telemetry: description: The latest telemetry details example: pressure: 3252 probed_at: 1623414482 water_flow: 0 water_temp: 17.1 properties: pressure: description: Pressure in millibar type: number probed_at: description: The Unix timestamp (in seconds) when the Sonic recorded measurements. type: number water_flow: description: The average water flow rate in milliliters per minute. type: number water_temp: description: "Water temperature in \xB0C" type: number title: Telemetry type: object UpdateRequest: properties: name: description: Signal name type: string title: UpdateRequest type: object AuthTokenResponse: type: object properties: token_details: oneOf: - type: string - type: object additionalProperties: true user_details: type: object additionalProperties: true HubDetailsResponse: description: Hub (bridge) details payload returned by the cloud platform. type: object additionalProperties: true example: id: "hub-REDACTED" serial_no: "REDACTED" status: "online" ApplianceCategoriesResponse: description: Appliance categories available for water-event/appliance classification. type: object additionalProperties: true example: categories: - id: "category-REDACTED" name: "Shower" UserServiceSignInRequest: description: Credentials payload for email/password sign-in. type: object properties: email: type: string format: email password: type: string example: email: "user@redacted.example" password: "REDACTED" UserServiceRefreshTokenRequest: description: Payload used to request a refreshed access token. type: object additionalProperties: true example: refresh_token: "REDACTED" UserServiceSignOutResponse: description: Logout acknowledgement payload. type: object additionalProperties: true example: success: true UserServiceUpdateUserRequest: description: Mutable user profile fields accepted by customer_app users update endpoint. type: object additionalProperties: true example: first_name: "Alex" last_name: "User" UserServiceUpdateUserResponse: description: Updated user profile payload. type: object additionalProperties: true example: id: "user-REDACTED" email: "user@redacted.example" PropertiesListResponse: description: List of customer properties available to the authenticated user. type: object additionalProperties: true example: properties: - id: "property-REDACTED" name: "Home" PropertyCreateRequest: description: Payload used to create a new property. type: object additionalProperties: true example: name: "Home" PropertyResponse: description: Property details payload. type: object additionalProperties: true example: id: "property-REDACTED" name: "Home" PropertyUpdateRequest: description: Payload used to update property metadata. type: object additionalProperties: true example: name: "Updated home" DeleteResponse: description: Generic delete acknowledgement payload. type: object additionalProperties: true example: deleted: true PropertyThingsResponse: description: List of things/devices assigned to a property. type: object additionalProperties: true example: things: - id: "thing-REDACTED" type: "sonic" MembershipsResponse: description: Property memberships payload. type: object additionalProperties: true example: memberships: - user_id: "user-REDACTED" role: "owner" MembershipInviteRequest: description: Payload used to invite a user to a property. type: object additionalProperties: true example: email: "invitee@redacted.example" role: "member" MembershipInviteResponse: description: Membership invitation result payload. type: object additionalProperties: true example: invitation_id: "invite-REDACTED" NotificationSettingsResponse: description: Notification settings payload for a property. type: object additionalProperties: true example: push_enabled: true NotificationSettingsUpdateRequest: description: Payload used to update property notification settings. type: object additionalProperties: true example: push_enabled: false PropertySettingsResponse: description: Property/device settings payload. type: object additionalProperties: true example: leak_protection_enabled: true PropertySettingsUpdateRequest: description: Payload used to update property/device settings. type: object additionalProperties: true example: leak_protection_enabled: false IncidentsResponse: description: Paginated incidents payload for a property. type: object additionalProperties: true example: incidents: - id: "incident-REDACTED" status: "active" IncidentResponse: description: Single incident details payload. type: object additionalProperties: true example: id: "incident-REDACTED" status: "active" IncidentActionRequest: description: Payload used to resolve, snooze or otherwise act on an incident. type: object additionalProperties: true example: action: "resolve" IncidentActionResponse: description: Incident action result payload. type: object additionalProperties: true example: status: "resolved" ThingResponse: description: Detailed Thing/device payload. type: object additionalProperties: true example: id: "thing-REDACTED" hub_id: "hub-REDACTED" ThingStateChangeRequest: description: Payload used to request a Thing state change. type: object additionalProperties: true example: action: "open" ThingStateChangeResponse: description: Thing state change acknowledgement payload. type: object additionalProperties: true example: status: "accepted" PressureTestTriggerRequest: description: Payload used to trigger pressure test execution. type: object additionalProperties: true example: source: "mobile" PressureTestTriggerResponse: description: Trigger pressure test response payload. type: object additionalProperties: true example: job_id: "pressure-test-REDACTED" PressureTestsResponse: description: Historical pressure test results for a Thing. type: object additionalProperties: true example: tests: - id: "test-REDACTED" result: "passed" PressureTestsCalendarResponse: description: Calendar grouped pressure test response. type: object additionalProperties: true example: by_day: "2026-01-01": - id: "test-REDACTED" CurrentDailyUsageResponse: description: Current-day water usage payload. type: object additionalProperties: true example: day_usage_liters: 0 AggregatedStatsResponse: description: Aggregated usage statistics payload. type: object additionalProperties: true example: total_usage_liters: 0 DailyUsageResponse: description: Daily usage time-series payload. type: object additionalProperties: true example: daily: - date: "2026-01-01" liters: 0 ThingEventsResponse: description: Water events payload for a Thing. type: object additionalProperties: true example: events: - started_at: "2026-01-01T00:00:00Z" flow_ml_per_min: 0 securitySchemes: BearerAuth: description: 'Send bearer token in header: Authorization: Bearer REDACTED.' type: http scheme: bearer bearerFormat: JWT info: title: Watergate Cloud API version: 2025.1.0 openapi: 3.0.0 paths: /ape/v1/incidents: get: callbacks: {} operationId: Ape.Controllers.IncidentController.index parameters: - description: '' in: query name: type required: false schema: description: Incident type enum: - high_volume_alert - long_flow_alert - device_handle_moved - battery_too_low_to_move_handle - radio_disconnection - cloud_disconnection - pressure_test_failed - pressure_test_skipped - pressure_test_aborted - health_check_failed - low_battery_level - legionella_risk - legionella_high_risk - low_water_temperature - water_presence_detected - low_temperature - high_temperature - high_humidity - advanced_valve_misalignment - backup_battery_usage type: string - description: '' in: query name: open required: false schema: description: Indicates whether the incident is open or closed. type: boolean - description: Page number that is used for the pagination. in: query name: page required: false schema: type: integer responses: '200': content: application/json: schema: $ref: '#/components/schemas/IncidentPaginatedResponse' description: Incident response '400': description: Bad request '401': description: Unauthorized '403': description: Forbidden '422': content: application/json: schema: $ref: '#/components/schemas/JsonErrorResponse' description: Unprocessable Entity summary: Retrieve all accessible incidents tags: - Incidents /ape/v1/incidents/{id}: get: callbacks: {} operationId: Ape.Controllers.IncidentController.show parameters: - description: Incident UUID in: path name: id required: true schema: type: string responses: '200': content: application/json: schema: $ref: '#/components/schemas/Incident' description: Incident response '400': description: Bad request '401': description: Unauthorized '403': description: Forbidden '422': content: application/json: schema: $ref: '#/components/schemas/JsonErrorResponse' description: Unprocessable Entity summary: Get an incident tags: - Incidents /ape/v1/incidents/{incident_id}/action: put: callbacks: {} operationId: Ape.Controllers.IncidentController.trigger_action parameters: - description: Incident UUID in: path name: incident_id required: true schema: type: string requestBody: content: application/json: schema: $ref: '#/components/schemas/IncidentAction' description: Body required: false responses: '200': content: application/json: schema: $ref: '#/components/schemas/Incident' description: Incident response '400': description: Bad request '401': description: Unauthorized '403': description: Forbidden '422': content: application/json: schema: $ref: '#/components/schemas/JsonErrorResponse' description: Unprocessable Entity summary: Transition an incident to a different state tags: - Incidents /ape/v1/properties: get: callbacks: {} operationId: Ape.Controllers.PropertyController.index parameters: - description: Property name in: query name: name required: false schema: type: string - description: 'Membership role of requesting user, one of: owner, user, guest.' in: query name: membership_role required: false schema: type: string - description: Search parameter to filter properties in: query name: search required: false schema: type: string - description: Page number that is used for the pagination. in: query name: page required: false schema: type: integer responses: '200': content: application/json: schema: $ref: '#/components/schemas/PropertiesPaginatedResponse' description: OK '400': description: Bad request '401': description: Unauthorized '403': description: Forbidden '422': content: application/json: schema: $ref: '#/components/schemas/JsonErrorResponse' description: Unprocessable Entity summary: Retrieve all accessible properties tags: - Properties /ape/v1/properties/{id}: get: callbacks: {} operationId: Ape.Controllers.PropertyController.show parameters: - description: Property UUID in: path name: id required: true schema: type: string responses: '200': content: application/json: schema: $ref: '#/components/schemas/Property' description: OK '400': description: Bad request '401': description: Unauthorized '403': description: Forbidden '422': content: application/json: schema: $ref: '#/components/schemas/JsonErrorResponse' description: Unprocessable Entity summary: Get property tags: - Properties patch: callbacks: {} operationId: Ape.Controllers.PropertyController.update parameters: - description: Property UUID in: path name: id required: true schema: type: string requestBody: content: application/json: schema: $ref: '#/components/schemas/PropertyUpdate' description: Body required: false responses: '200': content: application/json: schema: $ref: '#/components/schemas/Property' description: OK '400': description: Bad request '401': description: Unauthorized '403': description: Forbidden '422': content: application/json: schema: $ref: '#/components/schemas/JsonErrorResponse' description: Unprocessable Entity summary: Modify property tags: - Properties put: callbacks: {} operationId: Ape.Controllers.PropertyController.update_2 parameters: - description: Property UUID in: path name: id required: true schema: type: string requestBody: content: application/json: schema: $ref: '#/components/schemas/PropertyUpdate' description: Body required: false responses: '200': content: application/json: schema: $ref: '#/components/schemas/Property' description: OK '400': description: Bad request '401': description: Unauthorized '403': description: Forbidden '422': content: application/json: schema: $ref: '#/components/schemas/JsonErrorResponse' description: Unprocessable Entity summary: Modify property tags: - Properties /ape/v1/properties/{property_id}/incidents: get: callbacks: {} operationId: Ape.Controllers.IncidentController.index_property_incidents parameters: - description: '' in: query name: type required: false schema: description: Incident type enum: - high_volume_alert - long_flow_alert - device_handle_moved - battery_too_low_to_move_handle - radio_disconnection - cloud_disconnection - pressure_test_failed - pressure_test_skipped - pressure_test_aborted - health_check_failed - low_battery_level - legionella_risk - legionella_high_risk - low_water_temperature - water_presence_detected - low_temperature - high_temperature - high_humidity - advanced_valve_misalignment - backup_battery_usage type: string - description: '' in: query name: open required: false schema: description: Whether the incident is opened or closed type: boolean - description: Property UUID in: path name: property_id required: true schema: type: string - description: Page number that is used for the pagination. in: query name: page required: false schema: type: integer responses: '200': content: application/json: schema: $ref: '#/components/schemas/IncidentPaginatedResponse' description: Incident response '400': description: Bad request '401': description: Unauthorized '403': description: Forbidden '404': content: application/json: schema: $ref: '#/components/schemas/EmptyResponse' description: Not found '422': content: application/json: schema: $ref: '#/components/schemas/JsonErrorResponse' description: Unprocessable Entity summary: Retrieve all incidents for property tags: - Incidents - Properties /ape/v1/properties/{property_id}/notifications: get: callbacks: {} operationId: Ape.Controllers.NotificationController.get parameters: - description: Property UUID in: path name: property_id required: true schema: type: string responses: '200': content: application/json: schema: $ref: '#/components/schemas/NotificationSettings' description: OK '400': description: Bad request '401': description: Unauthorized '403': description: Forbidden '422': content: application/json: schema: $ref: '#/components/schemas/JsonErrorResponse' description: Unprocessable Entity summary: Get property notification settings tags: - Property settings - Properties put: callbacks: {} operationId: Ape.Controllers.NotificationController.put parameters: - description: Property UUID in: path name: property_id required: true schema: type: string requestBody: content: application/json: schema: $ref: '#/components/schemas/NotificationSettings' description: Body required: false responses: '200': content: application/json: schema: $ref: '#/components/schemas/NotificationSettings' description: OK '400': description: Bad request '401': description: Unauthorized '403': description: Forbidden '422': content: application/json: schema: $ref: '#/components/schemas/JsonErrorResponse' description: Unprocessable Entity summary: Modify property notification settings tags: - Property settings - Properties /ape/v1/properties/{property_id}/settings: get: callbacks: {} operationId: Ape.Controllers.PropertySettingsController.get parameters: - description: Property UUID in: path name: property_id required: true schema: type: string responses: '200': content: application/json: schema: $ref: '#/components/schemas/PropertySettings' description: OK '400': description: Bad request '401': description: Unauthorized '403': description: Forbidden '422': content: application/json: schema: $ref: '#/components/schemas/JsonErrorResponse' description: Unprocessable Entity summary: Get property settings tags: - Property settings - Properties put: callbacks: {} operationId: Ape.Controllers.PropertySettingsController.put parameters: - description: Property UUID in: path name: property_id required: true schema: type: string requestBody: content: application/json: schema: $ref: '#/components/schemas/PropertySettings' description: Body required: false responses: '200': content: application/json: schema: $ref: '#/components/schemas/PropertySettings' description: OK '400': description: Bad request '401': description: Unauthorized '403': description: Forbidden '422': content: application/json: schema: $ref: '#/components/schemas/JsonErrorResponse' description: Unprocessable Entity summary: Modify property settings tags: - Property settings - Properties /ape/v1/properties/{property_id}/signals: get: callbacks: {} operationId: Ape.Controllers.SignalController.index_property_signals parameters: - description: Property UUID in: path name: property_id required: true schema: type: string - description: Page number that is used for the pagination. in: query name: page required: false schema: type: integer responses: '200': content: application/json: schema: $ref: '#/components/schemas/SignalsPaginatedResponse' description: OK '400': description: Bad request '401': description: Unauthorized '403': description: Forbidden '404': content: application/json: schema: $ref: '#/components/schemas/EmptyResponse' description: Not found '422': content: application/json: schema: $ref: '#/components/schemas/JsonErrorResponse' description: Unprocessable Entity summary: Retrieve all Signals for property tags: - Signals - Properties /ape/v1/signals: get: callbacks: {} operationId: Ape.Controllers.SignalController.index parameters: - description: Signal name in: query name: name required: false schema: type: string - description: Page number that is used for the pagination. in: query name: page required: false schema: type: integer responses: '200': content: application/json: schema: $ref: '#/components/schemas/SignalsPaginatedResponse' description: OK '400': description: Bad request '401': description: Unauthorized '403': description: Forbidden '422': content: application/json: schema: $ref: '#/components/schemas/JsonErrorResponse' description: Unprocessable Entity summary: Retrieve all accessible Signals tags: - Signals /ape/v1/signals/{id}: get: callbacks: {} operationId: Ape.Controllers.SignalController.show parameters: - description: Signal UUID in: path name: id required: true schema: type: string responses: '200': content: application/json: schema: $ref: '#/components/schemas/Signal' description: OK '400': description: Bad request '401': description: Unauthorized '403': description: Forbidden '404': content: application/json: schema: $ref: '#/components/schemas/EmptyResponse' description: Not found '422': content: application/json: schema: $ref: '#/components/schemas/JsonErrorResponse' description: Unprocessable Entity summary: Get Signal tags: - Signals patch: callbacks: {} operationId: Ape.Controllers.SignalController.update parameters: - description: Signal UUID in: path name: id required: true schema: type: string requestBody: content: application/json: schema: $ref: '#/components/schemas/UpdateRequest' description: Body required: false responses: '200': content: application/json: schema: $ref: '#/components/schemas/Signal' description: OK '400': description: Bad request '401': description: Unauthorized '403': description: Forbidden '422': content: application/json: schema: $ref: '#/components/schemas/JsonErrorResponse' description: Unprocessable Entity summary: Modify Signal tags: - Signals put: callbacks: {} operationId: Ape.Controllers.SignalController.update_2 parameters: - description: Signal UUID in: path name: id required: true schema: type: string requestBody: content: application/json: schema: $ref: '#/components/schemas/UpdateRequest' description: Body required: false responses: '200': content: application/json: schema: $ref: '#/components/schemas/Signal' description: OK '400': description: Bad request '401': description: Unauthorized '403': description: Forbidden '422': content: application/json: schema: $ref: '#/components/schemas/JsonErrorResponse' description: Unprocessable Entity summary: Modify Signal tags: - Signals /ape/v1/signals/{signal_id}/sonics: get: callbacks: {} operationId: Ape.Controllers.SonicController.index_signal_sonics parameters: - description: Signal UUID in: path name: signal_id required: true schema: type: string - description: Page number that is used for the pagination. in: query name: page required: false schema: type: integer responses: '200': content: application/json: schema: $ref: '#/components/schemas/SonicPaginatedResponse' description: Incident response '400': description: Bad request '401': description: Unauthorized '403': description: Forbidden '404': content: application/json: schema: $ref: '#/components/schemas/EmptyResponse' description: Not found '422': content: application/json: schema: $ref: '#/components/schemas/JsonErrorResponse' description: Unprocessable Entity summary: Retrieve all Sonics for a Signal tags: - Sonics - Signals /ape/v1/sonics: get: callbacks: {} operationId: Ape.Controllers.SonicController.index parameters: - description: Sonic name in: query name: name required: false schema: type: string - description: Page number that is used for the pagination. in: query name: page required: false schema: type: integer responses: '200': content: application/json: schema: $ref: '#/components/schemas/SonicPaginatedResponse' description: OK '400': description: Bad request '401': description: Unauthorized '403': description: Forbidden '422': content: application/json: schema: $ref: '#/components/schemas/JsonErrorResponse' description: Unprocessable Entity summary: Retrieve all accessible Sonics tags: - Sonics /ape/v1/sonics/{id}: get: callbacks: {} operationId: Ape.Controllers.SonicController.show parameters: - description: Sonic UUID in: path name: id required: true schema: type: string responses: '200': content: application/json: schema: $ref: '#/components/schemas/Sonic' description: OK '400': description: Bad request '401': description: Unauthorized '403': description: Forbidden '404': content: application/json: schema: $ref: '#/components/schemas/EmptyResponse' description: Not found '422': content: application/json: schema: $ref: '#/components/schemas/JsonErrorResponse' description: Unprocessable Entity summary: Get Sonic tags: - Sonics patch: callbacks: {} operationId: Ape.Controllers.SonicController.update parameters: - description: Sonic UUID in: path name: id required: true schema: type: string requestBody: content: application/json: schema: $ref: '#/components/schemas/SonicUpdateRequest' description: Body required: false responses: '200': content: application/json: schema: $ref: '#/components/schemas/Sonic' description: OK '400': description: Bad request '401': description: Unauthorized '403': description: Forbidden '404': content: application/json: schema: $ref: '#/components/schemas/EmptyResponse' description: Not found '422': content: application/json: schema: $ref: '#/components/schemas/JsonErrorResponse' description: Unprocessable Entity summary: Modify Sonic tags: - Sonics put: callbacks: {} operationId: Ape.Controllers.SonicController.update_2 parameters: - description: Sonic UUID in: path name: id required: true schema: type: string requestBody: content: application/json: schema: $ref: '#/components/schemas/SonicUpdateRequest' description: Body required: false responses: '200': content: application/json: schema: $ref: '#/components/schemas/Sonic' description: OK '400': description: Bad request '401': description: Unauthorized '403': description: Forbidden '404': content: application/json: schema: $ref: '#/components/schemas/EmptyResponse' description: Not found '422': content: application/json: schema: $ref: '#/components/schemas/JsonErrorResponse' description: Unprocessable Entity summary: Modify Sonic tags: - Sonics /ape/v1/sonics/{sonic_id}/telemetry: get: callbacks: {} operationId: Ape.Controllers.TelemetryController.get parameters: - description: Sonic UUID in: path name: sonic_id required: true schema: type: string responses: '200': content: application/json: schema: $ref: '#/components/schemas/Telemetry' description: OK '400': description: Bad request '401': description: Unauthorized '403': description: Forbidden '404': content: application/json: schema: $ref: '#/components/schemas/EmptyResponse' description: Not found '422': content: application/json: schema: $ref: '#/components/schemas/JsonErrorResponse' description: Unprocessable Entity summary: Get the latest telemetry details tags: - Telemetry details /ape/v1/sonics/{sonic_id}/valve: put: callbacks: {} operationId: Ape.Controllers.ValveController.update parameters: - description: Sonic UUID in: path name: sonic_id required: true schema: type: string requestBody: content: application/json: schema: $ref: '#/components/schemas/SonicUpdateValveRequest' description: Body required: false responses: '200': description: OK '400': description: Bad request '401': description: Unauthorized '403': description: Forbidden '422': description: Unable to change the valve state at this moment as the state might be already changing. summary: Control the Sonic valve (open or close) tags: - Valve control /user-service/auth/sign_in: post: summary: "Email/password sign-in" description: "Authenticates a user with email and password and returns token/user details." operationId: Mobile_post_account_auth_sign_in tags: - "Authentication" security: [] requestBody: required: false content: application/json: schema: $ref: '#/components/schemas/UserServiceSignInRequest' responses: '200': description: User authenticated successfully. content: application/json: schema: $ref: '#/components/schemas/AuthTokenResponse' '401': description: Unauthorized '422': description: Unprocessable Entity /user-service/auth/refresh_token: put: summary: "Refreshes the JWT access token" description: "Refreshes the access token for an authenticated user session." operationId: Mobile_put_account_auth_refresh_token tags: - "Authentication" security: - BearerAuth: [] requestBody: required: false content: application/json: schema: $ref: '#/components/schemas/UserServiceRefreshTokenRequest' responses: '200': description: Token refreshed successfully. content: application/json: schema: $ref: '#/components/schemas/AuthTokenResponse' '401': description: Unauthorized /user-service/auth/validate_token: get: summary: "Validates the current token and returns refreshed token plus user details on app start" description: "Validates bearer token and returns session details for bootstrap/session-check flows." operationId: Mobile_get_account_auth_validate_token tags: - "Authentication" security: - BearerAuth: [] responses: '200': description: Token is valid. content: application/json: schema: $ref: '#/components/schemas/AuthTokenResponse' '401': description: Unauthorized /user-service/auth/sign_out: delete: summary: "Invalidates the current session server-side" description: "Invalidates current bearer session token." operationId: Mobile_delete_account_auth_sign_out tags: - "Authentication" security: - BearerAuth: [] responses: '200': description: Session invalidated successfully. content: application/json: schema: $ref: '#/components/schemas/UserServiceSignOutResponse' '401': description: Unauthorized /user-service/customer_app/users/{userId}: put: summary: "Updates the authenticated user profile" description: "Updates mutable user profile fields for a specific user identifier." operationId: Mobile_put_account_customer_app_users_userId tags: - "User profile" parameters: - in: path name: userId required: true schema: type: string security: - BearerAuth: [] requestBody: required: false content: application/json: schema: $ref: '#/components/schemas/UserServiceUpdateUserRequest' responses: '200': description: User profile updated successfully. content: application/json: schema: $ref: '#/components/schemas/UserServiceUpdateUserResponse' '401': description: Unauthorized /iot-core/customer_app/properties: get: summary: "Lists customer properties" description: "Returns the properties available to the authenticated customer." operationId: Mobile_get_app_properties tags: - "Properties" security: - BearerAuth: [] responses: '200': description: Properties returned successfully. content: application/json: schema: $ref: '#/components/schemas/PropertiesListResponse' '401': description: Unauthorized post: summary: "Creates a customer property" description: "Creates a new property for the authenticated customer." operationId: Mobile_post_app_properties tags: - "Properties" security: - BearerAuth: [] requestBody: required: false content: application/json: schema: $ref: '#/components/schemas/PropertyCreateRequest' responses: '200': description: Property created successfully. content: application/json: schema: $ref: '#/components/schemas/PropertyResponse' '401': description: Unauthorized /iot-core/customer_app/properties/{propertyId}: get: summary: "Returns property details" description: "Returns details for a selected customer property." operationId: Mobile_get_app_properties_propertyId tags: - "Properties" parameters: - in: path name: propertyId required: true schema: type: string security: - BearerAuth: [] responses: '200': description: Property details returned successfully. content: application/json: schema: $ref: '#/components/schemas/PropertyResponse' '401': description: Unauthorized put: summary: "Updates property details" description: "Updates metadata/settings for a selected customer property." operationId: Mobile_put_app_properties_propertyId tags: - "Properties" parameters: - in: path name: propertyId required: true schema: type: string security: - BearerAuth: [] requestBody: required: false content: application/json: schema: $ref: '#/components/schemas/PropertyUpdateRequest' responses: '200': description: Property updated successfully. content: application/json: schema: $ref: '#/components/schemas/PropertyResponse' '401': description: Unauthorized delete: summary: "Deletes a property" description: "Deletes a selected customer property." operationId: Mobile_delete_app_properties_propertyId tags: - "Properties" parameters: - in: path name: propertyId required: true schema: type: string security: - BearerAuth: [] responses: '200': description: Property deleted successfully. content: application/json: schema: $ref: '#/components/schemas/DeleteResponse' '401': description: Unauthorized /iot-core/customer_app/properties/{propertyId}/things: get: summary: "Returns the list of IoT devices (Sonics, Siryns, etc.)" description: "Returns all things/devices assigned to a selected property." operationId: Mobile_get_app_properties_propertyId_things tags: - "Devices" parameters: - in: path name: propertyId required: true schema: type: string security: - BearerAuth: [] responses: '200': description: Property things returned successfully. content: application/json: schema: $ref: '#/components/schemas/PropertyThingsResponse' '401': description: Unauthorized /iot-core/customer_app/properties/{propertyId}/memberships: get: summary: "Lists property memberships" description: "Returns membership entries for a selected property." operationId: Mobile_get_app_properties_propertyId_memberships tags: - "Property members" parameters: - in: path name: propertyId required: true schema: type: string security: - BearerAuth: [] responses: '200': description: Memberships returned successfully. content: application/json: schema: $ref: '#/components/schemas/MembershipsResponse' '401': description: Unauthorized post: summary: "Invites a user to join a property by email" description: "Creates a membership invitation for the selected property." operationId: Mobile_post_app_properties_propertyId_memberships tags: - "Property members" parameters: - in: path name: propertyId required: true schema: type: string security: - BearerAuth: [] requestBody: required: false content: application/json: schema: $ref: '#/components/schemas/MembershipInviteRequest' responses: '200': description: Membership invitation created successfully. content: application/json: schema: $ref: '#/components/schemas/MembershipInviteResponse' '401': description: Unauthorized /iot-core/customer_app/properties/{propertyId}/memberships/{userId}/expel: delete: summary: "Removes a user from property memberships" description: "Expels a member from the selected property." operationId: Mobile_delete_app_properties_propertyId_memberships_userId_expel tags: - "Property members" parameters: - in: path name: propertyId required: true schema: type: string - in: path name: userId required: true schema: type: string security: - BearerAuth: [] responses: '200': description: Member removed successfully. content: application/json: schema: $ref: '#/components/schemas/DeleteResponse' '401': description: Unauthorized /iot-core/customer_app/properties/{propertyId}/notification_settings: get: summary: "Returns notification settings for a property" description: "Returns customer notification settings configured for the selected property." operationId: Mobile_get_app_properties_propertyId_notification_settings tags: - "Notifications" parameters: - in: path name: propertyId required: true schema: type: string security: - BearerAuth: [] responses: '200': description: Notification settings returned successfully. content: application/json: schema: $ref: '#/components/schemas/NotificationSettingsResponse' '401': description: Unauthorized /iot-core/customer_app/properties/{propertyId}/update_notification_settings: put: summary: "Updates notification settings for a property" description: "Updates customer notification settings for the selected property." operationId: Mobile_put_app_properties_propertyId_update_notification_settings tags: - "Notifications" parameters: - in: path name: propertyId required: true schema: type: string security: - BearerAuth: [] requestBody: required: false content: application/json: schema: $ref: '#/components/schemas/NotificationSettingsUpdateRequest' responses: '200': description: Notification settings updated successfully. content: application/json: schema: $ref: '#/components/schemas/NotificationSettingsResponse' '401': description: Unauthorized /iot-core/customer_app/properties/{propertyId}/settings: get: summary: "Returns property device settings" description: "Returns current property-level device/settings configuration." operationId: Mobile_get_app_properties_propertyId_settings tags: - "Property settings" parameters: - in: path name: propertyId required: true schema: type: string security: - BearerAuth: [] responses: '200': description: Property settings returned successfully. content: application/json: schema: $ref: '#/components/schemas/PropertySettingsResponse' '401': description: Unauthorized /iot-core/customer_app/properties/{propertyId}/update_settings: put: summary: "Updates property device settings" description: "Updates property-level device/settings configuration." operationId: Mobile_put_app_properties_propertyId_update_settings tags: - "Property settings" parameters: - in: path name: propertyId required: true schema: type: string security: - BearerAuth: [] requestBody: required: false content: application/json: schema: $ref: '#/components/schemas/PropertySettingsUpdateRequest' responses: '200': description: Property settings updated successfully. content: application/json: schema: $ref: '#/components/schemas/PropertySettingsResponse' '401': description: Unauthorized /iot-core/customer_app/properties/{propertyId}/incidents: get: summary: "Paginated list of incidents" description: "Returns paginated incidents for a selected property." operationId: Mobile_get_app_properties_propertyId_incidents tags: - "Incidents" parameters: - in: path name: propertyId required: true schema: type: string security: - BearerAuth: [] responses: '200': description: Incidents returned successfully. content: application/json: schema: $ref: '#/components/schemas/IncidentsResponse' '401': description: Unauthorized /iot-core/customer_app/properties/{propertyId}/incidents/{incidentId}: get: summary: "Returns incident details" description: "Returns details for a single incident in the selected property." operationId: Mobile_get_app_properties_propertyId_incidents_incidentId tags: - "Incidents" parameters: - in: path name: propertyId required: true schema: type: string - in: path name: incidentId required: true schema: type: string security: - BearerAuth: [] responses: '200': description: Incident returned successfully. content: application/json: schema: $ref: '#/components/schemas/IncidentResponse' '401': description: Unauthorized /iot-core/customer_app/properties/{propertyId}/incidents/{incidentId}/action: put: summary: "Used for both resolving and snoozing incidents" description: "Executes an action (e.g. resolve/snooze) on a selected incident." operationId: Mobile_put_app_properties_propertyId_incidents_incidentId_action tags: - "Incidents" parameters: - in: path name: propertyId required: true schema: type: string - in: path name: incidentId required: true schema: type: string security: - BearerAuth: [] requestBody: required: false content: application/json: schema: $ref: '#/components/schemas/IncidentActionRequest' responses: '200': description: Incident action executed successfully. content: application/json: schema: $ref: '#/components/schemas/IncidentActionResponse' '401': description: Unauthorized /iot-core/customer_app/things/{thingId}: get: summary: "Fetches device details including the hub_id (Sonic UUID)" description: "Returns details for a specific Thing/device." operationId: Mobile_get_app_things_thingId tags: - "Devices" parameters: - in: path name: thingId required: true schema: type: string security: - BearerAuth: [] responses: '200': description: Thing details returned successfully. content: application/json: schema: $ref: '#/components/schemas/ThingResponse' '401': description: Unauthorized /iot-core/customer_app/things/{thingId}/state_change: post: summary: "Triggers valve open/close via cloud (Sonic device)" description: "Requests a state change command (e.g. valve open/close) for a Thing." operationId: Mobile_post_app_things_thingId_state_change tags: - "Valve control" parameters: - in: path name: thingId required: true schema: type: string security: - BearerAuth: [] requestBody: required: false content: application/json: schema: $ref: '#/components/schemas/ThingStateChangeRequest' responses: '200': description: State change command accepted. content: application/json: schema: $ref: '#/components/schemas/ThingStateChangeResponse' '401': description: Unauthorized /iot-core/customer_app/things/{thingId}/trigger_pressure_test: post: summary: "Triggers a pressure test" description: "Starts pressure test execution for a selected Thing." operationId: Mobile_post_app_things_thingId_trigger_pressure_test tags: - "Pressure testing" parameters: - in: path name: thingId required: true schema: type: string security: - BearerAuth: [] requestBody: required: false content: application/json: schema: $ref: '#/components/schemas/PressureTestTriggerRequest' responses: '200': description: Pressure test trigger accepted. content: application/json: schema: $ref: '#/components/schemas/PressureTestTriggerResponse' '401': description: Unauthorized /iot-core/customer_app/things/{thingId}/pressure_tests: get: summary: "Lists pressure test history" description: "Returns pressure test results for a selected Thing." operationId: Mobile_get_app_things_thingId_pressure_tests tags: - "Pressure testing" parameters: - in: path name: thingId required: true schema: type: string security: - BearerAuth: [] responses: '200': description: Pressure tests returned successfully. content: application/json: schema: $ref: '#/components/schemas/PressureTestsResponse' '401': description: Unauthorized /iot-core/customer_app/things/{thingId}/pressure_tests_calendar: get: summary: "Returns pressure test results for calendar view (date range filter)" description: "Returns pressure tests grouped for calendar/day-based UI rendering." operationId: Mobile_get_app_things_thingId_pressure_tests_calendar tags: - "Pressure testing" parameters: - in: path name: thingId required: true schema: type: string security: - BearerAuth: [] responses: '200': description: Pressure test calendar returned successfully. content: application/json: schema: $ref: '#/components/schemas/PressureTestsCalendarResponse' '401': description: Unauthorized /iot-core/customer_app/things/{thingId}/current_daily_usage: get: summary: "Returns current daily usage" description: "Returns current-day water usage for a selected Thing." operationId: Mobile_get_app_things_thingId_current_daily_usage tags: - "Water usage" parameters: - in: path name: thingId required: true schema: type: string security: - BearerAuth: [] responses: '200': description: Current daily usage returned successfully. content: application/json: schema: $ref: '#/components/schemas/CurrentDailyUsageResponse' '401': description: Unauthorized /iot-core/customer_app/things/{thingId}/aggregated_stats: get: summary: "Returns aggregated usage statistics" description: "Returns aggregated water usage statistics for a selected Thing." operationId: Mobile_get_app_things_thingId_aggregated_stats tags: - "Water usage" parameters: - in: path name: thingId required: true schema: type: string security: - BearerAuth: [] responses: '200': description: Aggregated statistics returned successfully. content: application/json: schema: $ref: '#/components/schemas/AggregatedStatsResponse' '401': description: Unauthorized /iot-core/customer_app/things/{thingId}/daily_usage: get: summary: "Returns daily usage history" description: "Returns daily water usage series for a selected Thing and optional month/year filters." operationId: Mobile_get_app_things_thingId_daily_usage tags: - "Water usage" parameters: - in: path name: thingId required: true schema: type: string - in: query name: month required: false schema: type: integer - in: query name: year required: false schema: type: integer security: - BearerAuth: [] responses: '200': description: Daily usage returned successfully. content: application/json: schema: $ref: '#/components/schemas/DailyUsageResponse' '401': description: Unauthorized /iot-core/customer_app/things/{thingId}/events: get: summary: "Lists Thing water events" description: "Returns water events detected for a selected Thing." operationId: Mobile_get_app_things_thingId_events tags: - "Water events" parameters: - in: path name: thingId required: true schema: type: string security: - BearerAuth: [] responses: '200': description: Thing events returned successfully. content: application/json: schema: $ref: '#/components/schemas/ThingEventsResponse' '401': description: Unauthorized /iot-core/customer_app/appliance_categories: get: summary: "Returns appliance categories used for event and usage classification" description: "Fetches appliance categories exposed to the customer app for assigning usage/events to appliance types." operationId: Mobile_get_app_appliance_categories tags: - "Appliance categories" security: - BearerAuth: [] responses: '200': description: Appliance categories returned successfully. content: application/json: schema: $ref: '#/components/schemas/ApplianceCategoriesResponse' examples: success: value: categories: - id: "category-REDACTED" name: "Shower" '401': description: Unauthorized /iot-core/customer_app/hubs/{hubId}: get: summary: "Returns details of a hub/bridge device" description: "Returns a detailed hub (bridge) payload for a given hub identifier used by the customer app." operationId: Mobile_get_app_hubs_hubId tags: - "Hubs (bridge)" parameters: - in: path name: hubId required: true schema: type: string security: - BearerAuth: [] responses: '200': description: Hub details returned successfully. content: application/json: schema: $ref: '#/components/schemas/HubDetailsResponse' examples: success: value: id: "hub-REDACTED" serial_no: "REDACTED" status: "online" '401': description: Unauthorized security: - BearerAuth: [] servers: - url: https://api.watergate.ai description: Production server