openapi: 3.0.3 info: title: 'WeatherGuardian API Documentation' description: '' version: 1.0.0 servers: - url: 'https://weather-guardian.com' tags: - name: Sensors description: '' components: securitySchemes: default: type: apiKey name: x-api-key in: header description: 'You can retrieve your token by visiting your dashboard and clicking Generate API token.' security: - default: [] paths: '/api/sensors/{sensor_id}/export': get: summary: 'Export sensor data' operationId: exportSensorData description: "Export data from a sensor. Only sensors you own (via its hub) or sensors marked as public can be exported.\n\n**Dates:** `from` and `to` accept ISO-8601 datetime strings (e.g. `2025-10-31T12:00:00Z`) **or** Unix timestamps\n(seconds or milliseconds; ms auto-detected by length). If `to` is omitted it defaults to \"now\". All processing is in **UTC**.\n`from` must be before (or equal to) `to`.\n\n**Aggregation shapes:**\n- `raw`: an array of raw measurements with fields: `observed_at` (ISO-8601), `temperature_c`, `humidity_pct`, `pressure_hpa`.\n- `hour`: grouped by **day**, then **hour** (0-23). For each metric you get `{ avg, min, max }`.\n- `day`: an array; each element is an object keyed by `YYYY-MM-DD`, whose value contains per-metric `{ avg, min, max }`." parameters: - in: query name: from description: 'Start of the range (inclusive). ISO-8601 or Unix timestamp (s or ms).' example: '2025-10-01T00:00:00Z' required: true schema: type: string description: 'Start of the range (inclusive). ISO-8601 or Unix timestamp (s or ms).' example: '2025-10-01T00:00:00Z' nullable: false - in: query name: to description: 'End of the range (inclusive). ISO-8601 or Unix timestamp (s or ms). Defaults to now.' example: '1730332799000' required: false schema: type: string description: 'End of the range (inclusive). ISO-8601 or Unix timestamp (s or ms). Defaults to now.' example: '1730332799000' nullable: false - in: query name: agg_type description: 'The aggregation level. One of: `raw`, `hour`, `day`.' example: hour required: true schema: type: string description: 'The aggregation level. One of: `raw`, `hour`, `day`.' example: hour nullable: false - in: header name: x-api-key description: '' example: '{YOUR_AUTH_KEY}' schema: type: string responses: 200: description: '' content: application/json: schema: oneOf: - description: raw type: object example: ok: true geohash: gcw2mn3 data: - observed_at: '2025-10-31T12:34:56Z' pressure_hpa: 1013.2 temperature_c: 19.8 humidity_pct: 62.1 - observed_at: '2025-10-31T12:35:56Z' pressure_hpa: 1013.1 temperature_c: 19.9 humidity_pct: 61.8 properties: ok: type: boolean example: true geohash: type: string example: gcw2mn3 data: type: array example: - observed_at: '2025-10-31T12:34:56Z' pressure_hpa: 1013.2 temperature_c: 19.8 humidity_pct: 62.1 - observed_at: '2025-10-31T12:35:56Z' pressure_hpa: 1013.1 temperature_c: 19.9 humidity_pct: 61.8 items: type: object properties: observed_at: type: string example: '2025-10-31T12:34:56Z' pressure_hpa: type: number example: 1013.2 temperature_c: type: number example: 19.8 humidity_pct: type: number example: 62.1 - description: hour type: object example: ok: true geohash: gcw2mn3 data: '2025-10-31': hours: '12': temperature: avg: 19.4 min: 18.9 max: 20.1 humidity: avg: 61.7 min: 59.2 max: 64.0 pressure: avg: 1012.9 min: 1012.4 max: 1013.5 '13': temperature: avg: 19.1 min: 18.6 max: 19.8 humidity: avg: 62.3 min: 60.1 max: 64.2 pressure: avg: 1012.6 min: 1012.1 max: 1013.0 properties: ok: type: boolean example: true geohash: type: string example: gcw2mn3 data: type: object properties: '2025-10-31': type: object properties: hours: type: object properties: 12: type: object properties: temperature: { type: object, properties: { avg: { type: number, example: 19.4 }, min: { type: number, example: 18.9 }, max: { type: number, example: 20.1 } } } humidity: { type: object, properties: { avg: { type: number, example: 61.7 }, min: { type: number, example: 59.2 }, max: { type: number, example: 64.0 } } } pressure: { type: object, properties: { avg: { type: number, example: 1012.9 }, min: { type: number, example: 1012.4 }, max: { type: number, example: 1013.5 } } } 13: type: object properties: temperature: { type: object, properties: { avg: { type: number, example: 19.1 }, min: { type: number, example: 18.6 }, max: { type: number, example: 19.8 } } } humidity: { type: object, properties: { avg: { type: number, example: 62.3 }, min: { type: number, example: 60.1 }, max: { type: number, example: 64.2 } } } pressure: { type: object, properties: { avg: { type: number, example: 1012.6 }, min: { type: number, example: 1012.1 }, max: { type: number, example: 1013.0 } } } - description: day type: object example: ok: true geohash: gcw2mn3 data: - '2025-10-30': temperature: avg: 18.7 min: 16.9 max: 20.8 humidity: avg: 63.2 min: 54.0 max: 71.4 pressure: avg: 1014.1 min: 1009.8 max: 1017.2 - '2025-10-31': temperature: avg: 18.1 min: 17.3 max: 19.4 humidity: avg: 64.5 min: 58.2 max: 69.9 pressure: avg: 1013.0 min: 1010.1 max: 1015.0 properties: ok: type: boolean example: true geohash: type: string example: gcw2mn3 data: type: array example: - '2025-10-30': temperature: avg: 18.7 min: 16.9 max: 20.8 humidity: avg: 63.2 min: 54 max: 71.4 pressure: avg: 1014.1 min: 1009.8 max: 1017.2 - '2025-10-31': temperature: avg: 18.1 min: 17.3 max: 19.4 humidity: avg: 64.5 min: 58.2 max: 69.9 pressure: avg: 1013 min: 1010.1 max: 1015 items: type: object properties: '2025-10-30': type: object properties: temperature: type: object properties: avg: type: number example: 18.7 min: type: number example: 16.9 max: type: number example: 20.8 humidity: type: object properties: avg: type: number example: 63.2 min: type: number example: 54.0 max: type: number example: 71.4 pressure: type: object properties: avg: type: number example: 1014.1 min: type: number example: 1009.8 max: type: number example: 1017.2 403: description: '' content: application/json: schema: type: object example: ok: false message: unauthorised properties: ok: type: boolean example: false message: type: string example: unauthorised 422: description: '' content: application/json: schema: oneOf: - description: '' type: object example: message: 'from date cannot be null' properties: message: type: string example: 'from date cannot be null' - description: '' type: object example: message: 'unable to parse from date' properties: message: type: string example: 'unable to parse from date' - description: '' type: object example: message: 'unable to parse to date' properties: message: type: string example: 'unable to parse to date' - description: '' type: object example: message: 'to date must be after from date' properties: message: type: string example: 'to date must be after from date' tags: - Sensors requestBody: required: true content: application/json: schema: type: object properties: from: type: string description: '' example: architecto nullable: false to: type: string description: '' example: architecto nullable: true agg_type: type: string description: '' example: raw nullable: false enum: - raw - hour - day required: - from - agg_type parameters: - in: path name: sensor_id description: 'The ID of the sensor.' example: SEN-089272C3AB30 required: true schema: type: string '/api/sensors/{sensor_id}/latest': get: summary: 'Export latest sensor measurement' operationId: exportLatestSensorMeasurement description: "Returns the latest measurement for a single sensor.\nOnly sensors you own (via its hub) or sensors marked as public can be queried.\n\nThe response payload is the `MeasurementResource` output for the sensor's `lastMeasurement`." parameters: - in: header name: x-api-key description: '' example: '{YOUR_AUTH_KEY}' schema: type: string responses: 200: description: ok content: application/json: schema: type: object example: observed_at: '2026-01-10T00:00:00Z' pressure_hpa: 1013.2 temperature_c: 19.8 humidity_pct: 62.1 battery_pct: 87 properties: observed_at: type: string example: '2026-01-10T00:00:00Z' pressure_hpa: type: number example: 1013.2 temperature_c: type: number example: 19.8 humidity_pct: type: number example: 62.1 battery_pct: type: integer example: 87 403: description: '' content: application/json: schema: type: object example: ok: false message: unauthorised properties: ok: type: boolean example: false message: type: string example: unauthorised 422: description: '' content: application/json: schema: type: string example: 'Data can only be exported from sensors' tags: - Sensors parameters: - in: path name: sensor_id description: 'The ID of the sensor.' example: SEN-089272C3AB30 required: true schema: type: string - in: path name: sensor description: 'The sensor device ID.' example: SEN-1234567890 required: true schema: type: string