PodQ Air is a backend platform for air-quality monitoring products. It combines sensor ingestion, indoor and outdoor air-quality data, weather context, location management, user access, alerts, historical trends, device operations, and app-facing APIs.
This reference documents the PodQ Air API for technical evaluation. Customer deployments are normally scoped with the PodQ Air team, including sensor integration, deployment model, client applications, dashboards, and operational workflows.
Authentication
Email/password, magic-link, and social login; access-token issue and refresh.
POST /auth/check-email Platform
Check if email exists
Check if email exists and return user's first/last name if it does
Parameters
request (body, required) — Email check request
curl -X POST "https://api.podqair.com/v2/auth/check-email" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected]"
}'
POST /auth/logout Platform
User logout
Logout the current user by revoking access and refresh tokens. Can be called with or without a valid token.
curl -X POST "https://api.podqair.com/v2/auth/logout" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json"
POST /auth/magic-link Platform
Send magic link
Send a passwordless authentication link to the user's email. The link is valid for 15 minutes.
Parameters
request (body, required) — Magic link request
curl -X POST "https://api.podqair.com/v2/auth/magic-link" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"client": "ios",
"email": "[email protected]",
"name": "John Doe",
"timezone": "America/New_York"
}'
GET /auth/magic-link/verify Platform
Verify magic link
Verify the magic link token and authenticate the user. Returns JWT tokens upon successful verification.
Parameters
token (query, required) — string — Magic link token from email
curl -X GET "https://api.podqair.com/v2/auth/magic-link/verify" \
-H "Authorization: Bearer <token>"
POST /auth/refresh Platform
Refresh access token
Generate a new access token using a valid refresh token. Returns both new access and refresh tokens with updated user data and location access.
Parameters
request (body, required) — Refresh token request
curl -X POST "https://api.podqair.com/v2/auth/refresh" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"refresh_token": "eyJhbGciOiJIUzI1NiIs..."
}'
POST /auth/register Platform
Register new user
Create a new user account with email and password. After successful registration, user must verify email and login separately.
Parameters
request (body, required) — Registration details
curl -X POST "https://api.podqair.com/v2/auth/register" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected]",
"password": "SecurePass123!"
}'
POST /auth/resend-verification Platform
Resend verification email
Resend email verification link to the user's email address. Can be used if the original email was not received or expired.
Parameters
request (body, required) — Resend verification request
curl -X POST "https://api.podqair.com/v2/auth/resend-verification" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected]"
}'
POST /auth/reset-password Platform
Request password reset
Send a password reset link to the user's email. For security, always returns success regardless of whether the email exists. Reset link is valid for 1 hour.
Parameters
request (body, required) — Password reset request
curl -X POST "https://api.podqair.com/v2/auth/reset-password" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected]"
}'
POST /auth/reset-password/confirm Platform
Confirm password reset
Complete the password reset by providing the token from email and a new password. Token is valid for 1 hour and can only be used once. All existing sessions are invalidated.
Parameters
request (body, required) — Password reset confirmation
curl -X POST "https://api.podqair.com/v2/auth/reset-password/confirm" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"new_password": "NewSecurePass123!",
"token": "random-base64-token-string"
}'
POST /auth/send-code Platform
Send verification code
Send a 6-digit verification code to the user's email. Valid for 10 minutes.
Parameters
request (body, required) — Code request
curl -X POST "https://api.podqair.com/v2/auth/send-code" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected]",
"first_name": "John",
"last_name": "Doe",
"timezone": "America/New_York"
}'
POST /auth/social-login Platform
Social login
Authenticate or register a user using social login providers (Google, Facebook, etc.). Creates a new account if the user doesn't exist.
Parameters
request (body, required) — Social login request
curl -X POST "https://api.podqair.com/v2/auth/social-login" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected]",
"name": "John Doe",
"oauth_id": "1234567890",
"provider": "google"
}'
POST /auth/verify-code Platform
Verify code
Verify a 6-digit code and authenticate user
Parameters
request (body, required) — Code verification
curl -X POST "https://api.podqair.com/v2/auth/verify-code" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"code": "123456",
"email": "[email protected]",
"first_name": "John",
"last_name": "Doe"
}'
POST /auth/verify-email Platform
Verify email address
Verify user's email address using the token sent to their email. Token can only be used once.
Parameters
request (body, required) — Email verification request
curl -X POST "https://api.podqair.com/v2/auth/verify-email" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"token": "verification-token-from-email"
}'
Users
User profile, account management, and pending location invitations.
POST /users/accept-invitation Platform
Accept location invitation
Accept a pending invitation to join a location
Parameters
request (body, required) — Invitation ID or invitation token
curl -X POST "https://api.podqair.com/v2/users/accept-invitation" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"invitation_id": "<string>",
"invitation_token": "<string>"
}'
POST /users/check-access Platform
Check user access status
Check if a user exists, has an invitation, or needs to complete registration
Parameters
request (body, required) — User email
curl -X POST "https://api.podqair.com/v2/users/check-access" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"email": "<string>"
}'
POST /users/decline-invitation Platform
Decline location invitation
Decline a pending invitation to join a location
Parameters
request (body, required) — Invitation ID
curl -X POST "https://api.podqair.com/v2/users/decline-invitation" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"invitation_id": "<string>"
}'
GET /users/invitations Platform
Get user's pending invitations
Get all pending location invitations for the authenticated user
curl -X GET "https://api.podqair.com/v2/users/invitations" \
-H "Authorization: Bearer <token>"
GET /users/me App support
Get current user profile
Get the authenticated user's complete profile information including ID, email, name, role, and account status.
curl -X GET "https://api.podqair.com/v2/users/me" \
-H "Authorization: Bearer <token>"
PUT /users/me App support
Update user profile
Update the authenticated user's profile information. Email changes require verification (not yet implemented).
Parameters
request (body, required) — Profile update details
curl -X PUT "https://api.podqair.com/v2/users/me" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"company": "<string>",
"email": "<string>",
"first_name": "<string>",
"last_name": "<string>",
"phone_number": "<string>"
}'
DELETE /users/me App support
Delete user account
Permanently delete the authenticated user's account. Requires password confirmation. This action cannot be undone.
Parameters
request (body, required) — Account deletion confirmation
curl -X DELETE "https://api.podqair.com/v2/users/me" \
-H "Authorization: Bearer <token>"
POST /users/me/change-password App support
Change password
Change the authenticated user's password. Requires current password for verification.
Parameters
request (body, required) — Password change details
curl -X POST "https://api.podqair.com/v2/users/me/change-password" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"current_password": "<string>",
"new_password": "<string>"
}'
GET /users/me/device-preferences Sensor operations
List device preferences
List device preferences for the authenticated user, optionally filtered by device or location
Parameters
device_id (query) — string — Filter by device IDlocation_id (query) — string — Filter by location ID
curl -X GET "https://api.podqair.com/v2/users/me/device-preferences" \
-H "Authorization: Bearer <token>"
POST /users/me/device-preferences Sensor operations
Set a device preference
Set the per-device location/sensor/display preference for the authenticated user
Parameters
request (body, required) — Device preference (device_id, location_id, primary_sensor_id, display_mode, applies_to_all_devices)
curl -X POST "https://api.podqair.com/v2/users/me/device-preferences" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json"
DELETE /users/me/device-preferences Sensor operations
Delete a device preference
Delete a device preference by its ID for the authenticated user
Parameters
preference_id (query, required) — string — Preference ID
curl -X DELETE "https://api.podqair.com/v2/users/me/device-preferences" \
-H "Authorization: Bearer <token>"
GET /users/me/devices Sensor operations
List devices
List all registered devices for the authenticated user
curl -X GET "https://api.podqair.com/v2/users/me/devices" \
-H "Authorization: Bearer <token>"
POST /users/me/devices Sensor operations
Register a device
Register a push/notification device for the authenticated user
Parameters
request (body, required) — Device registration (device_id, device_name, device_type)
curl -X POST "https://api.podqair.com/v2/users/me/devices" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json"
PUT /users/me/devices/{device_id} Sensor operations
Rename a device
Update the display name of a registered device
Parameters
device_id (path, required) — string — Device IDrequest (body, required) — New device name (device_name)
curl -X PUT "https://api.podqair.com/v2/users/me/devices/{device_id}" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json"
DELETE /users/me/devices/{device_id} Sensor operations
Delete a device
Remove a registered device for the authenticated user
Parameters
device_id (path, required) — string — Device ID
curl -X DELETE "https://api.podqair.com/v2/users/me/devices/{device_id}" \
-H "Authorization: Bearer <token>"
GET /users/me/devices/{device_id}/check-registration Sensor operations
Check device registration
Check whether a device is still active or needs re-registration
Parameters
device_id (path, required) — string — Device ID
curl -X GET "https://api.podqair.com/v2/users/me/devices/{device_id}/check-registration" \
-H "Authorization: Bearer <token>"
GET /users/me/home-bootstrap App support
Home screen bootstrap
Single best-effort payload with everything needed to render the Home screen
curl -X GET "https://api.podqair.com/v2/users/me/home-bootstrap" \
-H "Authorization: Bearer <token>"
GET /users/me/preferences/onboarding-completed App support
Get onboarding status
Get whether the authenticated user has completed onboarding
curl -X GET "https://api.podqair.com/v2/users/me/preferences/onboarding-completed" \
-H "Authorization: Bearer <token>"
PUT /users/me/preferences/onboarding-completed App support
Set onboarding status
Set whether the authenticated user has completed onboarding
Parameters
request (body, required) — Onboarding status (completed)
curl -X PUT "https://api.podqair.com/v2/users/me/preferences/onboarding-completed" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json"
GET /users/me/preferences/selected-location App support
Get selected location
Get the authenticated user's currently selected location ID (null if unset)
curl -X GET "https://api.podqair.com/v2/users/me/preferences/selected-location" \
-H "Authorization: Bearer <token>"
PUT /users/me/preferences/selected-location App support
Set selected location
Set the authenticated user's selected location ID
Parameters
request (body, required) — Selected location (location_id)
curl -X PUT "https://api.podqair.com/v2/users/me/preferences/selected-location" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json"
GET /users/me/preferences/widget-location App support
Get widget location
Get the authenticated user's home-screen widget location ID (null if unset)
curl -X GET "https://api.podqair.com/v2/users/me/preferences/widget-location" \
-H "Authorization: Bearer <token>"
PUT /users/me/preferences/widget-location App support
Set widget location
Set the authenticated user's home-screen widget location ID
Parameters
request (body, required) — Widget location (location_id)
curl -X PUT "https://api.podqair.com/v2/users/me/preferences/widget-location" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json"
PUT /users/me/profile App support Compatibility
Update user profile (v1 compatibility)
Update user profile name (splits into first/last name)
Parameters
request (body, required) — Profile update
curl -X PUT "https://api.podqair.com/v2/users/me/profile" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"name": "<string>"
}'
GET /users/me/startup-bootstrap App support
App startup bootstrap
Single payload of the data the app needs at startup (selected location, onboarding status, pending invitations, server time)
curl -X GET "https://api.podqair.com/v2/users/me/startup-bootstrap" \
-H "Authorization: Bearer <token>"
PATCH /users/profile Platform
Update user phone number
Update user's phone number (partial implementation)
Parameters
request (body, required) — Phone update
curl -X PATCH "https://api.podqair.com/v2/users/profile" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"phone_number": "<string>"
}'
Locations
Location management, membership, invitations, and per-location air-quality data.
POST /detected-events/{event_id}/outcome Platform
Set detected event outcome
Set the outcome (false_alert, real_alert, or hidden) for a detected event
Parameters
event_id (path, required) — string — Event IDrequest (body, required) — Event outcome
curl -X POST "https://api.podqair.com/v2/detected-events/{event_id}/outcome" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"outcome": "<string>"
}'
GET /locations Platform
List user locations
Get all locations the authenticated user has access to (owned or shared)
curl -X GET "https://api.podqair.com/v2/locations" \
-H "Authorization: Bearer <token>"
POST /locations Platform
Create new location
Create a new location for air quality monitoring. The authenticated user becomes the owner with full permissions.
Parameters
request (body, required) — Location details
curl -X POST "https://api.podqair.com/v2/locations" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"description": "My home office air quality monitoring",
"is_public": false,
"latitude": 40.7128,
"location_type": "default",
"longitude": -74.006,
"name": "Home Office",
"primary_language": "en",
"units_preference": "metric"
}'
GET /locations/{id} Platform
Get location by ID
Get detailed information about a specific location including sensor count and user role
Parameters
id (path, required) — string — Location ID
curl -X GET "https://api.podqair.com/v2/locations/{id}" \
-H "Authorization: Bearer <token>"
PUT /locations/{id} Platform
Update location
Update an existing location. Only the location owner can update location details.
Parameters
id (path, required) — string — Location IDrequest (body, required) — Updated location details
curl -X PUT "https://api.podqair.com/v2/locations/{id}" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"description": "My home office air quality monitoring - updated",
"is_public": false,
"latitude": 40.7128,
"longitude": -74.006,
"name": "Home Office - Updated",
"primary_language": "en",
"primary_outdoor_sensor_id": "550e8400-e29b-41d4-a716-446655440000",
"units_preference": "metric"
}'
DELETE /locations/{id} Platform
Delete location
Permanently delete a location. Only the location owner can delete. This action cannot be undone.
Parameters
id (path, required) — string — Location ID
curl -X DELETE "https://api.podqair.com/v2/locations/{id}" \
-H "Authorization: Bearer <token>"
GET /locations/{id}/ai-insights Platform
Get unified AI insights for location
Get priority-based, unified AI insights for a location. Shows only problematic metrics organized by indoor/outdoor sections. Filters based on user's personal and location-wide suppressions.
Parameters
id (path, required) — string — Location IDlanguage (query) — string — Language code (default: location's primary language or 'en')
curl -X GET "https://api.podqair.com/v2/locations/{id}/ai-insights" \
-H "Authorization: Bearer <token>"
GET /locations/{id}/card-insights Platform Deprecated Compatibility
DEPRECATED - Get card insights (returns empty)
DEPRECATED: Card insights feature has been removed. This endpoint returns empty for backwards compatibility. Use /locations/{id}/ai-insights instead.
Parameters
id (path, required) — string — Location IDcard_type (query) — string — Ignored - deprecated parameterlanguage (query) — string — Ignored - deprecated parameter
curl -X GET "https://api.podqair.com/v2/locations/{id}/card-insights" \
-H "Authorization: Bearer <token>"
GET /locations/{id}/invitations Platform
List location invitations
Get all pending invitations for a location
Parameters
id (path, required) — string — Location ID
curl -X GET "https://api.podqair.com/v2/locations/{id}/invitations" \
-H "Authorization: Bearer <token>"
POST /locations/{id}/invitations/cancel Platform
Cancel location invitation
Cancel a pending invitation to a location
Parameters
id (path, required) — string — Location IDrequest (body, required) — Email of invited user
curl -X POST "https://api.podqair.com/v2/locations/{id}/invitations/cancel" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected]"
}'
POST /locations/{id}/invite Platform
Send location invitation
Send an email invitation to a user to join a location
Parameters
id (path, required) — string — Location IDrequest (body, required) — Invitation details
curl -X POST "https://api.podqair.com/v2/locations/{id}/invite" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected]",
"message": "Join my location!",
"role": "location_user"
}'
POST /locations/{id}/invite/cancel Platform
Cancel a location invitation
Cancel a pending invitation to a location by invitee email
Parameters
id (path, required) — string — Location IDrequest (body, required) — Invitee email (email)
curl -X POST "https://api.podqair.com/v2/locations/{id}/invite/cancel" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json"
POST /locations/{id}/leave Platform
Leave a location
Allows a user to remove themselves from a location. If they are the only admin and there is exactly one other user, that user will be automatically promoted to admin.
Parameters
id (path, required) — string — Location ID
curl -X POST "https://api.podqair.com/v2/locations/{id}/leave" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json"
GET /locations/{id}/qr-code Platform
Generate QR code for location
Generate QR code data for sharing a location. Returns URL that can be encoded as QR code by client-side library.
Parameters
id (path, required) — string — Location ID
curl -X GET "https://api.podqair.com/v2/locations/{id}/qr-code" \
-H "Authorization: Bearer <token>"
POST /locations/{id}/sensors Sensor operations
Create sensor in location
Add a sensor to a location. Requires location owner or admin permissions.
Parameters
id (path, required) — string — Location IDrequest (body, required) — Sensor details
curl -X POST "https://api.podqair.com/v2/locations/{id}/sensors" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"device_url": "",
"is_active": true,
"is_public": false,
"name": "Living Room Sensor",
"sensor_id": "UUID for public sensors",
"sensor_type": "indoor_air_quality"
}'
POST /locations/{id}/sensors/indoor/register Sensor operations
Register indoor sensor to location
Register a YF10X or custom indoor sensor by device ID and link it to a location
Parameters
id (path, required) — string — Location IDrequest (body, required) — Sensor registration details
curl -X POST "https://api.podqair.com/v2/locations/{id}/sensors/indoor/register" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"device_id": "2025100712400006",
"force_register": false,
"name": "Living Room Sensor"
}'
GET /locations/{id}/sensors/{sensor_id} Sensor operations
Get sensor in location
Get details of a specific sensor in a location
Parameters
id (path, required) — string — Location IDsensor_id (path, required) — string — Sensor ID
curl -X GET "https://api.podqair.com/v2/locations/{id}/sensors/{sensor_id}" \
-H "Authorization: Bearer <token>"
PUT /locations/{id}/sensors/{sensor_id} Sensor operations
Update sensor in location
Update sensor details in a location. Requires location owner or admin permissions.
Parameters
id (path, required) — string — Location IDsensor_id (path, required) — string — Sensor IDrequest (body, required) — Sensor update details
curl -X PUT "https://api.podqair.com/v2/locations/{id}/sensors/{sensor_id}" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"buzzer_enabled": false,
"delta_pm": 3,
"delta_voc": 5,
"is_active": true,
"is_primary": false,
"is_public": false,
"last_time": 15,
"led_enabled": true,
"max_noise": 90,
"name": "Updated Sensor Name",
"offline_alert_after_minutes_override": 1440,
"sensor_type": "indoor_air_quality"
}'
DELETE /locations/{id}/sensors/{sensor_id} Sensor operations
Delete sensor from location
Remove a sensor from a location. Requires location owner or admin permissions.
Parameters
id (path, required) — string — Location IDsensor_id (path, required) — string — Sensor ID
curl -X DELETE "https://api.podqair.com/v2/locations/{id}/sensors/{sensor_id}" \
-H "Authorization: Bearer <token>"
GET /locations/{id}/sensors/{sensor_id}/readings Ingestion
Get sensor readings
Get readings for a specific sensor in a location
Parameters
id (path, required) — string — Location IDsensor_id (path, required) — string — Sensor IDlimit (query) — integer — Number of readings to returnoffset (query) — integer — Offset for pagination
curl -X GET "https://api.podqair.com/v2/locations/{id}/sensors/{sensor_id}/readings" \
-H "Authorization: Bearer <token>"
GET /locations/{id}/users Platform
Get location users
Get all users who have access to a location with their permissions
Parameters
id (path, required) — string — Location ID
curl -X GET "https://api.podqair.com/v2/locations/{id}/users" \
-H "Authorization: Bearer <token>"
POST /locations/{id}/users Platform
Add user to location
Add a user to a location with specified permissions. Only location owners can add users.
Parameters
id (path, required) — string — Location IDrequest (body, required) — User details
curl -X POST "https://api.podqair.com/v2/locations/{id}/users" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected]",
"permission": "viewer",
"role": "<string>",
"send_invite": true,
"user_email": "<string>"
}'
GET /locations/{id}/users/{userId} Platform
Get user permissions
Get the permissions for a specific user at a location
Parameters
id (path, required) — string — Location IDuserId (path, required) — string — User ID
curl -X GET "https://api.podqair.com/v2/locations/{id}/users/{userId}" \
-H "Authorization: Bearer <token>"
PUT /locations/{id}/users/{userId} Platform
Update user permissions
Update permissions for a user at a location. Only location owners can update permissions.
Parameters
id (path, required) — string — Location IDuserId (path, required) — string — User IDrequest (body, required) — Updated permissions
curl -X PUT "https://api.podqair.com/v2/locations/{id}/users/{userId}" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"permission": "editor",
"role": "<string>"
}'
DELETE /locations/{id}/users/{userId} Platform
Remove user from location
Remove a user's access to a location. Only location owners can remove users.
Parameters
id (path, required) — string — Location IDuserId (path, required) — string — User ID
curl -X DELETE "https://api.podqair.com/v2/locations/{id}/users/{userId}" \
-H "Authorization: Bearer <token>"
GET /locations/{id}/users/{userId}/permissions Platform
Get a user's location permissions
Get the permissions a specific user has at a location
Parameters
id (path, required) — string — Location IDuserId (path, required) — string — User ID
curl -X GET "https://api.podqair.com/v2/locations/{id}/users/{userId}/permissions" \
-H "Authorization: Bearer <token>"
GET /locations/{location_id}/detected-events Platform
List detected events
List detected air-quality events for a location
Parameters
location_id (path, required) — string — Location IDtype (query) — string — Filter by event typedays (query) — integer — Lookback window in daysinclude_hidden (query) — boolean — Include hidden events
curl -X GET "https://api.podqair.com/v2/locations/{location_id}/detected-events" \
-H "Authorization: Bearer <token>"
GET /public/locations Platform
List public locations
Get all publicly visible locations (no authentication required)
curl -X GET "https://api.podqair.com/v2/public/locations" \
-H "Authorization: Bearer <token>"
Sensors
Sensor onboarding (MQTT), ownership, readings, silencing, and discovery.
POST /airsense-alerts/{alert_id}/dismiss Platform
Dismiss a sensor alert
Dismiss a PodQ AirSense alert by ID
Parameters
alert_id (path, required) — string — Alert IDrequest (body) — Optional dismiss metadata
curl -X POST "https://api.podqair.com/v2/airsense-alerts/{alert_id}/dismiss" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"user_id": "<string>"
}'
POST /airsense-interventions/calculate-effectiveness Platform
Calculate intervention effectiveness
Analyzes 30-day before/after metrics to determine intervention effectiveness
Parameters
request (body, required) — Intervention ID
curl -X POST "https://api.podqair.com/v2/airsense-interventions/calculate-effectiveness" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"intervention_id": "<string>"
}'
GET /locations/{id}/sensors Sensor operations
List location sensors
Get all sensors for a specific location (public locations accessible without auth)
Parameters
id (path, required) — string — Location IDactive_only (query) — boolean — Return only active sensors
curl -X GET "https://api.podqair.com/v2/locations/{id}/sensors" \
-H "Authorization: Bearer <token>"
GET /locations/{id}/sensors/offline-status Sensor operations
Get sensor offline status
Get online/offline/silenced status for all sensors at a location
Parameters
id (path, required) — string — Location IDinclude_online (query) — boolean — Include online sensorsinclude_silenced (query) — boolean — Include silenced sensorssensor_types (query) — array — Filter by sensor types
curl -X GET "https://api.podqair.com/v2/locations/{id}/sensors/offline-status" \
-H "Authorization: Bearer <token>"
GET /locations/{location_id}/airsense-grades Historical data
Get pre-calculated AirSense grades for a location
Returns building performance grades (A+/A/B/C/D) for all indoor sensors at a location
Parameters
location_id (path, required) — string — Location ID
curl -X GET "https://api.podqair.com/v2/locations/{location_id}/airsense-grades" \
-H "Authorization: Bearer <token>"
GET /readings/aggregate Ingestion
Get aggregate sensor data
Get aggregated sensor data by time period (hour, day, week, month) for a location
Parameters
location_id (query, required) — string — Location IDsensor_type (query) — string — Sensor type filterperiod (query) — string — Aggregation period: hour, day, week, monthstart_time (query) — string — Start time (RFC3339 format)end_time (query) — string — End time (RFC3339 format)
curl -X GET "https://api.podqair.com/v2/readings/aggregate" \
-H "Authorization: Bearer <token>"
GET /readings/history Ingestion
Get sensor readings history
Get historical sensor readings for a time range
Parameters
location_id (query) — string — Location IDsensor_id (query) — string — Sensor IDstart_time (query) — string — Start time (RFC3339 format)end_time (query) — string — End time (RFC3339 format)limit (query) — integer — Maximum number of readings
curl -X GET "https://api.podqair.com/v2/readings/history" \
-H "Authorization: Bearer <token>"
GET /readings/latest Ingestion
Get latest readings (gRPC version)
Get the most recent sensor readings for all user locations
curl -X GET "https://api.podqair.com/v2/readings/latest" \
-H "Authorization: Bearer <token>"
POST /sensor-data Sensor operations
Submit sensor reading
Submit a single sensor reading with measurements (PM2.5, PM10, temperature, humidity, CO2, VOC, etc.)
Parameters
request (body, required) — Sensor reading data
curl -X POST "https://api.podqair.com/v2/sensor-data" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"metadata": {
"has_sensor1": true,
"has_sensor2": true,
"location": "<string>",
"sensor1_type": "<string>",
"sensor2_type": "<string>",
"sensor_brand": "<string>",
"sensor_type": "<string>"
},
"readings": {
"aqi": 0,
"aqi_category": "<string>",
"aqi_type": "<string>",
"co2": 0,
"humidity": 0,
"pm1": 0,
"pm10": 0,
"pm10_alt": 0,
"pm10_sens1": 0,
"pm10_sens2": 0,
"pm1_alt": 0,
"pm1_sens1": 0,
"pm1_sens2": 0,
"pm25": 0,
"pm25_alt": 0,
"pm25_sens1": 0,
"pm25_sens2": 0,
"pm4": 0,
"pm4_alt": 0,
"pm4_sens1": 0,
"pm4_sens2": 0,
"sensor1_type": "<string>",
"sensor2_type": "<string>",
"temperature": 0,
"voc": 0
},
"sensor_id": "550e8400-e29b-41d4-a716-446655440000",
"source": "podq-sensor-v2",
"timestamp": 1705318200
}'
POST /sensor-data/bulk Sensor operations
Submit bulk sensor readings
Submit multiple sensor readings in a single request for efficient data collection
Parameters
request (body, required) — Bulk sensor readings data
curl -X POST "https://api.podqair.com/v2/sensor-data/bulk" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"readings": [
{
"metadata": {
"has_sensor1": true,
"has_sensor2": true,
"location": "<string>",
"sensor1_type": "<string>",
"sensor2_type": "<string>",
"sensor_brand": "<string>",
"sensor_type": "<string>"
},
"readings": {
"aqi": 0,
"aqi_category": "<string>",
"aqi_type": "<string>",
"co2": 0,
"humidity": 0,
"pm1": 0,
"pm10": 0,
"pm10_alt": 0,
"pm10_sens1": 0,
"pm10_sens2": 0,
"pm1_alt": 0,
"pm1_sens1": 0,
"pm1_sens2": 0,
"pm25": 0,
"pm25_alt": 0,
"pm25_sens1": 0,
"pm25_sens2": 0,
"pm4": 0,
"pm4_alt": 0,
"pm4_sens1": 0,
"pm4_sens2": 0,
"sensor1_type": "<string>",
"sensor2_type": "<string>",
"temperature": 0,
"voc": 0
},
"sensor_id": "550e8400-e29b-41d4-a716-446655440000",
"source": "podq-sensor-v2",
"timestamp": 1705318200
}
]
}'
POST /sensors Sensor operations
Register new sensor
Register a new sensor for a location. Requires permission to manage sensors for the location.
Parameters
request (body, required) — Sensor registration details
curl -X POST "https://api.podqair.com/v2/sensors" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"description": "Temperature sensor for living room monitoring",
"location_id": "550e8400-e29b-41d4-a716-446655440000",
"max_value": 50,
"min_value": -10,
"name": "Living Room Temperature",
"type": "temperature",
"unit": "celsius"
}'
POST /sensors/indoor/setup-credentials Sensor operations
Set up indoor sensor MQTT credentials
Pre-register MQTT credentials for a BLE-configured indoor device before it connects
Parameters
request (body, required) — Device ID and password
curl -X POST "https://api.podqair.com/v2/sensors/indoor/setup-credentials" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"device_id": "<string>",
"password": "<string>"
}'
GET /sensors/indoor/unclaimed Sensor operations
List unclaimed indoor sensors
List indoor sensors that are actively reporting but not yet assigned to any location
Parameters
hours (query) — integer — Max hours since last reading (max 168)limit (query) — integer — Max results (max 50)
curl -X GET "https://api.podqair.com/v2/sensors/indoor/unclaimed" \
-H "Authorization: Bearer <token>"
POST /sensors/indoor/verify-credentials Sensor operations
Verify indoor sensor MQTT credentials
Verify a password matches the stored hash for a device (detects BLE transmission errors)
Parameters
request (body, required) — Device ID and password to verify
curl -X POST "https://api.podqair.com/v2/sensors/indoor/verify-credentials" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"device_id": "<string>",
"password": "<string>"
}'
GET /sensors/indoor/{device_id}/connection-status Sensor operations
Get indoor sensor connection status
Check whether an indoor device has connected and reported data (used after BLE WiFi setup)
Parameters
device_id (path, required) — string — Device ID
curl -X GET "https://api.podqair.com/v2/sensors/indoor/{device_id}/connection-status" \
-H "Authorization: Bearer <token>"
GET /sensors/indoor/{device_id}/mqtt-status Sensor operations
Get indoor sensor MQTT credential status
Check whether an indoor device has MQTT credentials configured
Parameters
device_id (path, required) — string — Device ID
curl -X GET "https://api.podqair.com/v2/sensors/indoor/{device_id}/mqtt-status" \
-H "Authorization: Bearer <token>"
GET /sensors/list Sensor operations
Get all sensors for correlation analysis
Returns all indoor and outdoor sensors with multipliers
curl -X GET "https://api.podqair.com/v2/sensors/list" \
-H "Authorization: Bearer <token>"
GET /sensors/outdoor/public Weather/context
Get public outdoor sensors
Get all public outdoor sensors available for user selection during onboarding
curl -X GET "https://api.podqair.com/v2/sensors/outdoor/public" \
-H "Authorization: Bearer <token>"
GET /sensors/public/nearby Sensor operations
List nearby public sensors
List public sensors within a radius of a coordinate, sorted by distance (no auth required)
Parameters
lat (query, required) — number — Latitudelon (query, required) — number — Longituderadius (query) — number — Search radius in kmlimit (query) — integer — Max results (max 100)
curl -X GET "https://api.podqair.com/v2/sensors/public/nearby" \
-H "Authorization: Bearer <token>"
POST /sensors/silence Sensor operations
Silence a sensor
Silence offline alerts for a single sensor
Parameters
request (body, required) — Silence request
curl -X POST "https://api.podqair.com/v2/sensors/silence" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"location_id": "<string>",
"reason": "<string>",
"sensor_id": "<string>",
"sensor_type": "<string>",
"silence_type": "<string>",
"silenced_until": "<string>"
}'
POST /sensors/silence-bulk Sensor operations
Silence sensors in bulk
Silence offline alerts for multiple sensors at a location
Parameters
request (body, required) — Bulk silence request
curl -X POST "https://api.podqair.com/v2/sensors/silence-bulk" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"location_id": "<string>",
"reason": "<string>",
"sensor_ids": [
"<string>"
],
"sensor_types": [
"<string>"
],
"silence_type": "<string>",
"silenced_until": "<string>"
}'
DELETE /sensors/unsilence Sensor operations
Unsilence a sensor
Remove an offline-alert silence for a sensor
Parameters
sensor_id (query, required) — string — Sensor IDsensor_type (query, required) — string — Sensor type
curl -X DELETE "https://api.podqair.com/v2/sensors/unsilence" \
-H "Authorization: Bearer <token>"
POST /sensors/yf10x/events Ingestion
Submit YF10X sensor event (vape/bullying detection)
Accepts vape or bullying detection events from YF10X sensors
Parameters
event (body, required) — Event data
curl -X POST "https://api.podqair.com/v2/sensors/yf10x/events" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"device_id": "<string>",
"event_type": "<string>",
"raw_json": "<string>",
"timestamp": 0
}'
POST /sensors/yf10x/readings Ingestion
Submit YF10X sensor reading
Accepts YF10X sensor data from MQTT gateway and forwards to api-core
Parameters
reading (body, required) — Sensor reading data
curl -X POST "https://api.podqair.com/v2/sensors/yf10x/readings" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"atm": 0,
"c2h5oh": 0,
"ch4": 0,
"co": 0,
"co2": 0,
"consumed_airtime": 0,
"data_rate": "<string>",
"device_id": "<string>",
"ex": 0,
"f_cnt": 0,
"gateway_count": 0,
"h2": 0,
"h2s": 0,
"hcho": 0,
"humidity": 0,
"lux": 0,
"motion": 0,
"nh3": 0,
"no": 0,
"no2": 0,
"noise": 0,
"nox": 0,
"o2": 0,
"o3": 0,
"pm1.0": 0,
"pm10": 0,
"pm2.5": 0,
"product_model": "<string>",
"rssi": 0,
"sensor_timestamp": 0,
"snr": 0,
"so2": 0,
"temperature": 0,
"tvoc": 0
}'
GET /sensors/{device_id}/ownership Sensor operations
Get sensor ownership status
Check whether a device is claimed and whether the current user can claim/reconfigure it
Parameters
device_id (path, required) — string — Device ID
curl -X GET "https://api.podqair.com/v2/sensors/{device_id}/ownership" \
-H "Authorization: Bearer <token>"
GET /sensors/{id} Sensor operations
Get sensor by ID
Get detailed information about a specific sensor
Parameters
id (path, required) — string — Sensor ID
curl -X GET "https://api.podqair.com/v2/sensors/{id}" \
-H "Authorization: Bearer <token>"
PUT /sensors/{id} Sensor operations
Update sensor
Update sensor details. Requires permission to manage sensors for the location.
Parameters
id (path, required) — string — Sensor IDrequest (body, required) — Updated sensor details
curl -X PUT "https://api.podqair.com/v2/sensors/{id}" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"description": "Updated description",
"max_value": 50,
"min_value": -10,
"name": "Living Room Temperature - Updated",
"status": "active"
}'
DELETE /sensors/{id} Sensor operations
Delete sensor
Permanently delete a sensor. Requires permission to manage sensors for the location.
Parameters
id (path, required) — string — Sensor ID
curl -X DELETE "https://api.podqair.com/v2/sensors/{id}" \
-H "Authorization: Bearer <token>"
GET /sensors/{sensor_id}/airsense-alerts Sensor operations
List sensor alerts
List PodQ AirSense alerts for a sensor
Parameters
sensor_id (path, required) — string — Sensor IDinclude_dismissed (query) — boolean — Include dismissed alertsdays (query) — integer — Lookback window in days
curl -X GET "https://api.podqair.com/v2/sensors/{sensor_id}/airsense-alerts" \
-H "Authorization: Bearer <token>"
GET /sensors/{sensor_id}/airsense-history Historical data
Get historical AirSense grades for a sensor
Returns daily grade snapshots across multiple timeframes (1d, 3d, 7d, 14d) for trend analysis
Parameters
sensor_id (path, required) — string — Indoor Sensor IDdays (query) — integer — Number of days of history to fetch (default 14, max 30)
curl -X GET "https://api.podqair.com/v2/sensors/{sensor_id}/airsense-history" \
-H "Authorization: Bearer <token>"
GET /sensors/{sensor_id}/airsense-interventions Sensor operations
Get intervention history for a sensor
Retrieves all logged maintenance interventions for a sensor with before/after metrics
Parameters
sensor_id (path, required) — string — Indoor Sensor IDdays (query) — integer — Number of days of history (default 90)
curl -X GET "https://api.podqair.com/v2/sensors/{sensor_id}/airsense-interventions" \
-H "Authorization: Bearer <token>"
POST /sensors/{sensor_id}/airsense-interventions Sensor operations
Log a maintenance intervention
Records a maintenance action (filter change, HVAC repair, etc.) for a sensor
Parameters
sensor_id (path, required) — string — Indoor Sensor IDrequest (body, required) — Intervention details
curl -X POST "https://api.podqair.com/v2/sensors/{sensor_id}/airsense-interventions" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"intervention_date": "2025-11-08T10:00:00Z",
"intervention_type": "filter_change",
"notes": "Replaced MERV-13 filter",
"user_id": "<string>"
}'
POST /sensors/{sensor_id}/command Sensor operations
Send command to YF10X sensor
Sends a command to a YF10X sensor via MQTT (e.g., threshold configuration)
Parameters
sensor_id (path, required) — string — Sensor device ID (e.g., 2512010132)command (body, required) — Command to send
curl -X POST "https://api.podqair.com/v2/sensors/{sensor_id}/command" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"buzzer": true,
"delta_pm": 0,
"delta_voc": 0,
"last_time": 0,
"led": true,
"max_noise": 0,
"raw_command": [
0
]
}'
Environmental
Indoor and outdoor AQI, weather, UV index, and heat-index data and history.
GET /environmental-bands/overrides Platform
List environmental band overrides
List per-location environmental band overrides for a location
Parameters
location_id (query, required) — string — Location ID
curl -X GET "https://api.podqair.com/v2/environmental-bands/overrides" \
-H "Authorization: Bearer <token>"
POST /environmental-bands/overrides Platform
Create an environmental band override
Create a per-location override for an environmental band (color, max value, name, etc.)
Parameters
request (body, required) — Override (location_id, metric_type, band_key required; optional max_value, color, text_color, band_name, description, reason)
curl -X POST "https://api.podqair.com/v2/environmental-bands/overrides" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json"
PUT /environmental-bands/overrides/{id} Platform
Update an environmental band override
Update an existing per-location environmental band override by ID
Parameters
id (path, required) — integer — Override IDrequest (body, required) — Fields to update (max_value, color, text_color, band_name, description, reason)
curl -X PUT "https://api.podqair.com/v2/environmental-bands/overrides/{id}" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json"
DELETE /environmental-bands/overrides/{id} Platform
Delete an environmental band override
Delete a per-location environmental band override by ID
Parameters
id (path, required) — integer — Override ID
curl -X DELETE "https://api.podqair.com/v2/environmental-bands/overrides/{id}" \
-H "Authorization: Bearer <token>"
GET /environmental/air-quality Platform
Get air quality
Get combined environmental air-quality data. Not yet implemented — currently returns 501.
curl -X GET "https://api.podqair.com/v2/environmental/air-quality" \
-H "Authorization: Bearer <token>"
GET /environmental/heat-index Platform
Get heat index
Calculate heat index (feels-like temperature) based on temperature and humidity
Parameters
location_id (query) — string — Location IDcity_id (query) — string — City ID (alternative to location_id)
curl -X GET "https://api.podqair.com/v2/environmental/heat-index" \
-H "Authorization: Bearer <token>"
GET /environmental/heat-index/history Historical data
Get heat index history
Get historical heat index data for a location
Parameters
location_id (query, required) — string — Location IDstart_date (query) — string — Start date (YYYY-MM-DD)end_date (query) — string — End date (YYYY-MM-DD)interval (query) — string — Data interval (hour, day)
curl -X GET "https://api.podqair.com/v2/environmental/heat-index/history" \
-H "Authorization: Bearer <token>"
GET /environmental/hourly Platform
Get hourly environmental forecast
Get comprehensive hourly forecast including weather, AQI, UV index, and heat index
Parameters
location_id (query, required) — string — Location IDhours_before (query) — integer — Hours of history to include (max 24)hours_after (query) — integer — Hours of forecast to include (max 48)
curl -X GET "https://api.podqair.com/v2/environmental/hourly" \
-H "Authorization: Bearer <token>"
GET /environmental/uv-index Platform
Get UV index
Get current and hourly UV index forecast for a location
Parameters
location_id (query) — string — Location IDcity_id (query) — string — City ID (alternative to location_id)interval (query) — string — Forecast interval
curl -X GET "https://api.podqair.com/v2/environmental/uv-index" \
-H "Authorization: Bearer <token>"
GET /indoor-aqi/aggregate Weather/context
Get aggregate indoor AQI
Get aggregate indoor air quality across all sensors (fast, no per-sensor breakdown)
Parameters
location_id (query, required) — string — Location ID
curl -X GET "https://api.podqair.com/v2/indoor-aqi/aggregate" \
-H "Authorization: Bearer <token>"
GET /indoor-aqi/current Weather/context
Get current indoor AQI
Get the current indoor Air Quality Index for a location based on sensor data
Parameters
location (query, required) — string — Location ID
curl -X GET "https://api.podqair.com/v2/indoor-aqi/current" \
-H "Authorization: Bearer <token>"
GET /indoor-aqi/history Weather/context
Get indoor AQI history
Get historical indoor air quality data for a location
Parameters
location_id (query, required) — string — Location IDstart_date (query) — string — Start date (YYYY-MM-DD)end_date (query) — string — End date (YYYY-MM-DD)interval (query) — string — Data interval (hour, day)
curl -X GET "https://api.podqair.com/v2/indoor-aqi/history" \
-H "Authorization: Bearer <token>"
GET /indoor-aqi/metric-history Weather/context
Get multi-metric history
Get historical data for any metric type (CO₂, AQI, PM2.5, temperature, etc.) with multi-sensor aggregation
Parameters
location_id (query, required) — string — Location IDmetric (query, required) — string — Metric type (aqi, co2, pm25, tvoc, hcho, temperature, humidity)hours (query) — integer — Hours of history (1, 6, 24, 168, 720)interval (query) — string — Data interval (1minute, 5minute, 10minute, 1hour, 6hour)sensor_id (query) — string — Specific sensor ID (omit for aggregated)aggregation (query) — string — Aggregation type (all, avg, min, max)
curl -X GET "https://api.podqair.com/v2/indoor-aqi/metric-history" \
-H "Authorization: Bearer <token>"
GET /indoor-aqi/statistics Weather/context
Get indoor AQI statistics
Get aggregate indoor AQI statistics for a location. Not yet implemented — currently returns 501.
Parameters
location (query) — string — Location ID
curl -X GET "https://api.podqair.com/v2/indoor-aqi/statistics" \
-H "Authorization: Bearer <token>"
GET /indoor-aqi/{sensor_id}/history Weather/context
Get indoor AQI history by sensor
Get historical indoor AQI readings for a specific sensor over a time range
Parameters
sensor_id (path, required) — string — Sensor IDstart_date (query) — string — Range start (RFC3339); defaults to 24h agoend_date (query) — string — Range end (RFC3339); defaults to nowinterval (query) — string — Aggregation interval
curl -X GET "https://api.podqair.com/v2/indoor-aqi/{sensor_id}/history" \
-H "Authorization: Bearer <token>"
GET /locations/{id}/outdoor-aqi Weather/context
Get current outdoor AQI
Get the current outdoor Air Quality Index for a location or public sensor
Parameters
location_id (query) — string — Location IDsensor_id (query) — string — Public Sensor ID
curl -X GET "https://api.podqair.com/v2/locations/{id}/outdoor-aqi" \
-H "Authorization: Bearer <token>"
GET /outdoor-aqi/current Weather/context
Get current outdoor AQI
Get the current outdoor Air Quality Index for a location or public sensor
Parameters
location_id (query) — string — Location IDsensor_id (query) — string — Public Sensor ID
curl -X GET "https://api.podqair.com/v2/outdoor-aqi/current" \
-H "Authorization: Bearer <token>"
GET /outdoor-aqi/forecast Weather/context
Get outdoor AQI forecast
Get hourly outdoor air quality forecast for a location
Parameters
location_id (query, required) — string — Location IDhours (query) — integer — Number of hours to forecast (max 100)
curl -X GET "https://api.podqair.com/v2/outdoor-aqi/forecast" \
-H "Authorization: Bearer <token>"
GET /outdoor-aqi/history Weather/context
Get outdoor AQI history
Get historical outdoor air quality data for a location. Use either hours parameter OR start_date/end_date range.
Parameters
location_id (query, required) — string — Location IDhours (query) — integer — Number of hours of historical data (e.g., 24, 168 for 7 days, 720 for 30 days)start_date (query) — string — Start date (YYYY-MM-DD or ISO8601 format)end_date (query) — string — End date (YYYY-MM-DD or ISO8601 format)interval (query) — string — Data interval (5minute, 10minute, 1hour, 6hour, day)
curl -X GET "https://api.podqair.com/v2/outdoor-aqi/history" \
-H "Authorization: Bearer <token>"
GET /outdoor-aqi/map Weather/context
Get nearby outdoor AQI for map
Get outdoor AQI for sensors near a coordinate, for map display
Parameters
lat (query, required) — number — Latitudelon (query, required) — number — Longituderadius (query, required) — number — Search radius in kmlimit (query, required) — integer — Maximum number of sensors
curl -X GET "https://api.podqair.com/v2/outdoor-aqi/map" \
-H "Authorization: Bearer <token>"
GET /outdoor-aqi/metric-history Weather/context
Get outdoor AQI metric history
Get historical data for outdoor AQI metrics with multi-sensor support
Parameters
location_id (query) — string — Location ID (required if sensor_id not provided)metric (query, required) — string — Metric type (aqi, pm25, pm10)hours (query) — integer — Hours of history (default 24, max 168)interval (query) — string — Data interval (1minute, 5minute, 10minute, 1hour)sensor_id (query) — string — Sensor ID (required if location_id not provided)breakdown (query) — string — individual or aggregated (default aggregated)
curl -X GET "https://api.podqair.com/v2/outdoor-aqi/metric-history" \
-H "Authorization: Bearer <token>"
GET /outdoor-aqi/nearby Weather/context
Get nearby outdoor AQI
Get outdoor AQI for sensors near a coordinate (alias of /outdoor-aqi/map)
Parameters
lat (query, required) — number — Latitudelon (query, required) — number — Longituderadius (query, required) — number — Search radius in kmlimit (query, required) — integer — Maximum number of sensors
curl -X GET "https://api.podqair.com/v2/outdoor-aqi/nearby" \
-H "Authorization: Bearer <token>"
GET /outdoor-aqi/widget Weather/context
Get outdoor AQI for iOS widget
Lightweight endpoint returning minimal AQI data optimized for iOS widgets with user-configured bands
Parameters
location_id (query, required) — string — Location ID
curl -X GET "https://api.podqair.com/v2/outdoor-aqi/widget" \
-H "Authorization: Bearer <token>"
GET /outdoor/nearest Weather/context
Get AQI and weather for nearest outdoor sensor
Returns AQI, weather, and sensor info for the nearest outdoor sensor based on GPS coordinates
Parameters
lat (query, required) — number — Latitudelon (query, required) — number — Longitude
curl -X GET "https://api.podqair.com/v2/outdoor/nearest" \
-H "Authorization: Bearer <token>"
GET /uvindex/history Historical data
Get UV index history
Get historical UV index readings for a location over a time range
Parameters
location_id (query, required) — string — Location IDstart_date (query) — string — Range start (RFC3339)end_date (query) — string — Range end (RFC3339)interval (query) — string — Aggregation interval
curl -X GET "https://api.podqair.com/v2/uvindex/history" \
-H "Authorization: Bearer <token>"
GET /weather/current Weather/context
Get current weather
Get current weather conditions for a location from Tomorrow.io
Parameters
location_id (query) — string — Location IDcity_id (query) — string — City ID (alternative to location_id)
curl -X GET "https://api.podqair.com/v2/weather/current" \
-H "Authorization: Bearer <token>"
GET /weather/daily-forecast Weather/context
Get daily weather forecast
Get daily weather forecast summaries for a location
Parameters
location_id (query) — string — Location IDcity_id (query) — string — City ID (alternative to location_id)days (query) — integer — Number of days to forecast (max 7)
curl -X GET "https://api.podqair.com/v2/weather/daily-forecast" \
-H "Authorization: Bearer <token>"
GET /weather/forecast Weather/context
Get weather forecast
Get hourly weather forecast for a location
Parameters
location_id (query) — string — Location IDcity_id (query) — string — City ID (alternative to location_id)hours (query) — integer — Number of hours to forecast (max 120)
curl -X GET "https://api.podqair.com/v2/weather/forecast" \
-H "Authorization: Bearer <token>"
GET /weather/mappings Weather/context
Get weather code mappings
Get weather code mappings with descriptions and icons for a language
Parameters
language (query) — string — Language code
curl -X GET "https://api.podqair.com/v2/weather/mappings" \
-H "Authorization: Bearer <token>"
Notifications
Notification preferences, message logs, and delivery counts.
POST /notifications/allow-one-more Platform
Allow one more message today
Allow sending one additional message today beyond normal limits
Parameters
request (body, required) — Allow one more request
curl -X POST "https://api.podqair.com/v2/notifications/allow-one-more" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"channel": "<string>",
"location_id": "<string>",
"message_type": "<string>",
"user_email": "<string>"
}'
GET /notifications/message-logs Platform
Get message logs
Get message delivery logs for a specific user and location
Parameters
location_id (query, required) — string — Location IDuser_id (query, required) — string — User IDlimit (query) — integer — Maximum number of logs to return
curl -X GET "https://api.podqair.com/v2/notifications/message-logs" \
-H "Authorization: Bearer <token>"
GET /notifications/messages/today Platform
Get today's sent messages
Get list of messages sent today for the user and location
Parameters
location_id (query) — string — Location ID
curl -X GET "https://api.podqair.com/v2/notifications/messages/today" \
-H "Authorization: Bearer <token>"
GET /notifications/sensor-alert-preferences Sensor operations
List sensor alert preferences
List the authenticated user's sensor alert preferences, optionally filtered by location/metric
Parameters
location_id (query) — string — Filter by location IDmetric_type (query) — string — Filter by metric type
curl -X GET "https://api.podqair.com/v2/notifications/sensor-alert-preferences" \
-H "Authorization: Bearer <token>"
POST /notifications/sensor-alert-preferences Sensor operations
Create or update a sensor alert preference
Create or update a sensor alert preference for the authenticated user
Parameters
request (body, required) — Sensor alert preference
curl -X POST "https://api.podqair.com/v2/notifications/sensor-alert-preferences" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json"
DELETE /notifications/sensor-alert-preferences/{id} Sensor operations
Delete a sensor alert preference
Delete a sensor alert preference by ID for the authenticated user
Parameters
id (path, required) — string — Preference ID
curl -X DELETE "https://api.podqair.com/v2/notifications/sensor-alert-preferences/{id}" \
-H "Authorization: Bearer <token>"
GET /notifications/sensor-metrics Sensor operations
List available sensor metrics
List sensor metrics available for alerting, optionally filtered to a location
Parameters
location_id (query) — string — Filter metrics to a location
curl -X GET "https://api.podqair.com/v2/notifications/sensor-metrics" \
-H "Authorization: Bearer <token>"
GET /notifications/today Platform
Get today's notification counts
Get today's notification message counts per type and channel for a location
Parameters
location_id (query, required) — string — Location ID
curl -X GET "https://api.podqair.com/v2/notifications/today" \
-H "Authorization: Bearer <token>"
GET /users/notification-preferences/{location_id} App support
Get notification preferences
Get user's notification preferences for a specific location
Parameters
location_id (path, required) — string — Location ID
curl -X GET "https://api.podqair.com/v2/users/notification-preferences/{location_id}" \
-H "Authorization: Bearer <token>"
PUT /users/notification-preferences/{location_id} App support
Update notification preferences
Update user's notification preferences for a specific location
Parameters
location_id (path, required) — string — Location IDrequest (body, required) — Notification preferences
curl -X PUT "https://api.podqair.com/v2/users/notification-preferences/{location_id}" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"daily_forecast_email": true,
"daily_forecast_push": true,
"daily_forecast_time": [
0
],
"daily_forecast_whatsapp": true,
"quiet_hours_enabled": true,
"quiet_hours_end": [
0
],
"quiet_hours_start": [
0
],
"whatsapp_number": "<string>"
}'