{"openapi":"3.1.0","info":{"title":"Awair (BYOK) API","version":"0.1.0","description":"Awair (BYOK) lets an AI assistant read your own Awair data through the Awair API with a key you supply (Awair developer access token). Read-only: 9 tools (get_user_info, list_devices, get_device_api_usage, get_latest_air_data, get_raw_air_data, get_5_minute_air_data, get_15_minute_air_data, get_device_power_status, get_device_timezone). The BYOK key travels with each request, is used for that one...\n\nEvery operation is read-only or compute-only. The same tools are available over MCP (streamable HTTP) at https://byok-awair.connectorbay.com/mcp.","contact":{"name":"Unify Dynamics LLC","email":"agent@connectorbay.com","url":"https://connectorbay.com/byok-awair/docs"},"termsOfService":"https://connectorbay.com/byok-awair/terms"},"servers":[{"url":"https://byok-awair.connectorbay.com"}],"externalDocs":{"url":"https://connectorbay.com/byok-awair/docs"},"security":[{"upstreamKey":[]}],"components":{"securitySchemes":{"bearer":{"type":"http","scheme":"bearer","description":"Optional. A Pro API key raises rate limits; no credentials are required."},"upstreamKey":{"type":"apiKey","in":"header","name":"X-Upstream-Key","description":"Your own key for the service this connector wraps (bring your own key). Used for that one call only; never stored, logged or cached."}},"schemas":{"Error":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object"}}}}},"paths":{"/v1/tools/get_user_info":{"post":{"operationId":"get_user_info","summary":"Show the Awair developer account tier, the daily request quota per endpoint and today's usage. Email and birth year are ","description":"Show the Awair developer account tier, the daily request quota per endpoint and today's usage. Email and birth year are left out. Use for \"What is my Awair API tier and how many requests are left today\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{},"title":"get_user_infoArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/list_devices":{"post":{"operationId":"list_devices","summary":"List the Awair devices the account owns with name, type, id, room and space type, preference and timezone. Coordinates a","description":"List the Awair devices the account owns with name, type, id, room and space type, preference and timezone. Coordinates and location names are left out. Use for \"Which Awair devices do I have\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{},"title":"list_devicesArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/get_device_api_usage":{"post":{"operationId":"get_device_api_usage","summary":"Show how many API calls today each air-data endpoint has used for one device. Use for \"How many Awair API calls has my d","description":"Show how many API calls today each air-data endpoint has used for one device. Use for \"How many Awair API calls has my device used today\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"device_type":{"description":"Device type as returned by list_devices (deviceType), for example awair-r2 or awair-element.","maxLength":40,"title":"Device Type","type":"string"},"device_id":{"description":"Numeric device id as returned by list_devices (deviceId).","maximum":2147483647,"minimum":0,"title":"Device Id","type":"integer"}},"required":["device_type","device_id"],"title":"get_device_api_usageArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/get_latest_air_data":{"post":{"operationId":"get_latest_air_data","summary":"Get the newest air data point of a device: Awair score, temperature, humidity, CO2, VOC and PM2.5 readings and their ind","description":"Get the newest air data point of a device: Awair score, temperature, humidity, CO2, VOC and PM2.5 readings and their indices. Empty when the device sent nothing in the last 10 minutes. Hobbyist quota: 300 calls a day. Use for \"How is the air quality in my bedroom right now\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"device_type":{"description":"Device type as returned by list_devices (deviceType), for example awair-r2 or awair-element.","maxLength":40,"title":"Device Type","type":"string"},"device_id":{"description":"Numeric device id as returned by list_devices (deviceId).","maximum":2147483647,"minimum":0,"title":"Device Id","type":"integer"},"fahrenheit":{"anyOf":[{"type":"boolean"},{"type":"null"}],"default":false,"description":"True to return temperature in Fahrenheit instead of Celsius.","title":"Fahrenheit"}},"required":["device_type","device_id"],"title":"get_latest_air_dataArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/get_raw_air_data":{"post":{"operationId":"get_raw_air_data","summary":"Get raw air data (about 10-second points) for up to one hour, back at most 30 days. Hobbyist quota: 500 calls a day. Use","description":"Get raw air data (about 10-second points) for up to one hour, back at most 30 days. Hobbyist quota: 500 calls a day. Use for \"Show my Awair CO2 readings for the last half hour\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"device_type":{"description":"Device type as returned by list_devices (deviceType), for example awair-r2 or awair-element.","maxLength":40,"title":"Device Type","type":"string"},"device_id":{"description":"Numeric device id as returned by list_devices (deviceId).","maximum":2147483647,"minimum":0,"title":"Device Id","type":"integer"},"from_time":{"anyOf":[{"maxLength":40,"type":"string"},{"type":"null"}],"default":null,"description":"Start of the time range as ISO 8601 date or datetime; at most 1 hour are returned per call (default: 5 minutes before now).","title":"From Time"},"to_time":{"anyOf":[{"maxLength":40,"type":"string"},{"type":"null"}],"default":null,"description":"End of the time range as ISO 8601 date or datetime (default: now).","title":"To Time"},"limit":{"anyOf":[{"maximum":360,"minimum":1,"type":"integer"},{"type":"null"}],"default":360,"description":"Number of data points (maximum about 360).","title":"Limit"},"desc":{"anyOf":[{"type":"boolean"},{"type":"null"}],"default":true,"description":"True (default) returns the newest points first counting back from the end time; false counts forward from the start time.","title":"Desc"},"fahrenheit":{"anyOf":[{"type":"boolean"},{"type":"null"}],"default":false,"description":"True to return temperature in Fahrenheit instead of Celsius.","title":"Fahrenheit"}},"required":["device_type","device_id"],"title":"get_raw_air_dataArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/get_5_minute_air_data":{"post":{"operationId":"get_5_minute_air_data","summary":"Get air data averaged over 5-minute blocks for up to 24 hours. Hobbyist quota: 300 calls a day. Use for \"What was my air","description":"Get air data averaged over 5-minute blocks for up to 24 hours. Hobbyist quota: 300 calls a day. Use for \"What was my air quality over the last 12 hours in 5-minute averages\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"device_type":{"description":"Device type as returned by list_devices (deviceType), for example awair-r2 or awair-element.","maxLength":40,"title":"Device Type","type":"string"},"device_id":{"description":"Numeric device id as returned by list_devices (deviceId).","maximum":2147483647,"minimum":0,"title":"Device Id","type":"integer"},"from_time":{"anyOf":[{"maxLength":40,"type":"string"},{"type":"null"}],"default":null,"description":"Start of the time range as ISO 8601 date or datetime; at most 24 hours are returned per call (default: 10 minutes before now).","title":"From Time"},"to_time":{"anyOf":[{"maxLength":40,"type":"string"},{"type":"null"}],"default":null,"description":"End of the time range as ISO 8601 date or datetime (default: now).","title":"To Time"},"limit":{"anyOf":[{"maximum":288,"minimum":1,"type":"integer"},{"type":"null"}],"default":288,"description":"Number of data points (maximum about 288).","title":"Limit"},"desc":{"anyOf":[{"type":"boolean"},{"type":"null"}],"default":true,"description":"True (default) returns the newest points first counting back from the end time; false counts forward from the start time.","title":"Desc"},"fahrenheit":{"anyOf":[{"type":"boolean"},{"type":"null"}],"default":false,"description":"True to return temperature in Fahrenheit instead of Celsius.","title":"Fahrenheit"}},"required":["device_type","device_id"],"title":"get_5_minute_air_dataArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/get_15_minute_air_data":{"post":{"operationId":"get_15_minute_air_data","summary":"Get air data averaged over 15-minute blocks for up to 7 days. Hobbyist quota: 100 calls a day. Use for \"How did CO2 and ","description":"Get air data averaged over 15-minute blocks for up to 7 days. Hobbyist quota: 100 calls a day. Use for \"How did CO2 and humidity in my room change over the past week\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"device_type":{"description":"Device type as returned by list_devices (deviceType), for example awair-r2 or awair-element.","maxLength":40,"title":"Device Type","type":"string"},"device_id":{"description":"Numeric device id as returned by list_devices (deviceId).","maximum":2147483647,"minimum":0,"title":"Device Id","type":"integer"},"from_time":{"anyOf":[{"maxLength":40,"type":"string"},{"type":"null"}],"default":null,"description":"Start of the time range as ISO 8601 date or datetime; at most 7 days are returned per call (default: 30 minutes before now).","title":"From Time"},"to_time":{"anyOf":[{"maxLength":40,"type":"string"},{"type":"null"}],"default":null,"description":"End of the time range as ISO 8601 date or datetime (default: now).","title":"To Time"},"limit":{"anyOf":[{"maximum":672,"minimum":1,"type":"integer"},{"type":"null"}],"default":672,"description":"Number of data points (maximum about 672).","title":"Limit"},"desc":{"anyOf":[{"type":"boolean"},{"type":"null"}],"default":true,"description":"True (default) returns the newest points first counting back from the end time; false counts forward from the start time.","title":"Desc"},"fahrenheit":{"anyOf":[{"type":"boolean"},{"type":"null"}],"default":false,"description":"True to return temperature in Fahrenheit instead of Celsius.","title":"Fahrenheit"}},"required":["device_type","device_id"],"title":"get_15_minute_air_dataArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/get_device_power_status":{"post":{"operationId":"get_device_power_status","summary":"Get the battery percentage and whether the device is plugged in. Use for \"Is my Awair device plugged in and how full is ","description":"Get the battery percentage and whether the device is plugged in. Use for \"Is my Awair device plugged in and how full is its battery\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"device_type":{"description":"Device type as returned by list_devices (deviceType), for example awair-r2 or awair-element.","maxLength":40,"title":"Device Type","type":"string"},"device_id":{"description":"Numeric device id as returned by list_devices (deviceId).","maximum":2147483647,"minimum":0,"title":"Device Id","type":"integer"}},"required":["device_type","device_id"],"title":"get_device_power_statusArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/get_device_timezone":{"post":{"operationId":"get_device_timezone","summary":"Get the timezone setting of a device. Use for \"Which timezone is my Awair device set to\".","description":"Get the timezone setting of a device. Use for \"Which timezone is my Awair device set to\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"device_type":{"description":"Device type as returned by list_devices (deviceType), for example awair-r2 or awair-element.","maxLength":40,"title":"Device Type","type":"string"},"device_id":{"description":"Numeric device id as returned by list_devices (deviceId).","maximum":2147483647,"minimum":0,"title":"Device Id","type":"integer"}},"required":["device_type","device_id"],"title":"get_device_timezoneArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}}}}