{"openapi":"3.1.0","info":{"title":"AirQo (BYOK) API","version":"0.1.0","description":"AirQo (BYOK) lets an AI assistant read your own AirQo data through the AirQo API with a key you supply (AirQo API access token). Read-only: 12 tools (list_grids, list_countries, list_sites, get_site, find_nearest_sites, list_devices, get_recent_grid_measurements, get_recent_cohort_measurements, get_daily_forecast, list_coverage_countries, list_country_monitors, get_coverage_impact). The BYOK key...\n\nEvery operation is read-only or compute-only. The same tools are available over MCP (streamable HTTP) at https://byok-airqo.connectorbay.com/mcp.","contact":{"name":"Unify Dynamics LLC","email":"agent@connectorbay.com","url":"https://connectorbay.com/byok-airqo/docs"},"termsOfService":"https://connectorbay.com/byok-airqo/terms"},"servers":[{"url":"https://byok-airqo.connectorbay.com"}],"externalDocs":{"url":"https://connectorbay.com/byok-airqo/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/list_grids":{"post":{"operationId":"list_grids","summary":"List the public AirQo grids (city and administrative-area groupings of monitoring sites) with their id, name, admin leve","description":"List the public AirQo grids (city and administrative-area groupings of monitoring sites) with their id, name, admin level and network. Use for \"Which cities does AirQo monitor air quality in\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"limit":{"anyOf":[{"maximum":2000,"minimum":1,"type":"integer"},{"type":"null"}],"default":1000,"description":"Maximum records to return (default 1000, max 2000).","title":"Limit"},"skip":{"anyOf":[{"minimum":0,"type":"integer"},{"type":"null"}],"default":0,"description":"Number of records to skip, for paging (default 0).","title":"Skip"}},"title":"list_gridsArguments","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_countries":{"post":{"operationId":"list_countries","summary":"List the countries where AirQo has air quality monitoring coverage. Use for \"In which countries does AirQo have air qual","description":"List the countries where AirQo has air quality monitoring coverage. Use for \"In which countries does AirQo have air quality monitors\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{},"title":"list_countriesArguments","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_sites":{"post":{"operationId":"list_sites","summary":"List public monitoring sites with name, coordinates, network and online status. Use for \"List AirQo air quality monitori","description":"List public monitoring sites with name, coordinates, network and online status. Use for \"List AirQo air quality monitoring sites\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"limit":{"anyOf":[{"maximum":2000,"minimum":1,"type":"integer"},{"type":"null"}],"default":1000,"description":"Maximum records to return (default 1000, max 2000).","title":"Limit"},"skip":{"anyOf":[{"minimum":0,"type":"integer"},{"type":"null"}],"default":0,"description":"Number of records to skip, for paging (default 0).","title":"Skip"}},"title":"list_sitesArguments","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_site":{"post":{"operationId":"get_site","summary":"Get full details of one monitoring site: coordinates, administrative context and current online status. Use for \"Show de","description":"Get full details of one monitoring site: coordinates, administrative context and current online status. Use for \"Show details of monitoring site 64f7b3e8c9d25a0013f2d456\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"site_id":{"description":"Site id from list_sites or find_nearest_sites.","maxLength":200,"title":"Site Id","type":"string"}},"required":["site_id"],"title":"get_siteArguments","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/find_nearest_sites":{"post":{"operationId":"find_nearest_sites","summary":"Find monitoring sites near a coordinate within a radius, closest first, with distance in km (site coordinates are offset","description":"Find monitoring sites near a coordinate within a radius, closest first, with distance in km (site coordinates are offset by up to about 0.5 km for privacy). Use for \"Which AirQo monitors are within 5 km of 0.3476, 32.5825\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"latitude":{"description":"Latitude with at least 5 decimal places, for example 0.34760.","title":"Latitude","type":"number"},"longitude":{"description":"Longitude with at least 5 decimal places, for example 32.58250.","title":"Longitude","type":"number"},"radius":{"description":"Search radius in kilometres.","minimum":0.1,"title":"Radius","type":"number"},"online_status":{"anyOf":[{"enum":["online","offline"],"type":"string"},{"type":"null"}],"default":null,"description":"Keep only online or offline sites.","title":"Online Status"},"limit":{"anyOf":[{"maximum":80,"minimum":1,"type":"integer"},{"type":"null"}],"default":30,"description":"Maximum records to return (default 30, max 80).","title":"Limit"}},"required":["latitude","longitude","radius"],"title":"find_nearest_sitesArguments","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 public sensor devices with category (lowcost, bam, gas), deployment status, site and last activity. Use for \"List A","description":"List public sensor devices with category (lowcost, bam, gas), deployment status, site and last activity. Use for \"List AirQo monitoring devices\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"limit":{"anyOf":[{"maximum":2000,"minimum":1,"type":"integer"},{"type":"null"}],"default":1000,"description":"Maximum records to return (default 1000, max 2000).","title":"Limit"},"skip":{"anyOf":[{"minimum":0,"type":"integer"},{"type":"null"}],"default":0,"description":"Number of records to skip, for paging (default 0).","title":"Skip"}},"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_recent_grid_measurements":{"post":{"operationId":"get_recent_grid_measurements","summary":"Get the latest hourly calibrated PM2.5 and PM10 measurements (about the last 7 days) from all public sites of a city gri","description":"Get the latest hourly calibrated PM2.5 and PM10 measurements (about the last 7 days) from all public sites of a city grid. Use for \"What is the recent air quality in Nairobi (grid 64b7ac8fd7249f0029feca80)\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"grid_id":{"description":"Grid id from list_grids, for example 64b7ac8fd7249f0029feca80 (Nairobi).","maxLength":200,"title":"Grid Id","type":"string"},"limit":{"anyOf":[{"maximum":80,"minimum":1,"type":"integer"},{"type":"null"}],"default":30,"description":"Maximum records to return (default 30, max 80).","title":"Limit"},"skip":{"anyOf":[{"minimum":0,"type":"integer"},{"type":"null"}],"default":0,"description":"Number of records to skip, for paging (default 0).","title":"Skip"}},"required":["grid_id"],"title":"get_recent_grid_measurementsArguments","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_recent_cohort_measurements":{"post":{"operationId":"get_recent_cohort_measurements","summary":"Get hourly calibrated PM2.5 and PM10 measurements (about the last 7 days on the Free plan) for a cohort of devices; use ","description":"Get hourly calibrated PM2.5 and PM10 measurements (about the last 7 days on the Free plan) for a cohort of devices; use the cohort id airqo-public for a network-wide sample. Use for \"What is the recent air quality across the AirQo network\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"cohort_id":{"description":"Cohort id; airqo-public gives a network-wide sample of public devices.","maxLength":200,"title":"Cohort Id","type":"string"},"start_time":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}],"default":null,"description":"Start of the window as an ISO 8601 timestamp.","title":"Start Time"},"end_time":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}],"default":null,"description":"End of the window as an ISO 8601 timestamp.","title":"End Time"},"limit":{"anyOf":[{"maximum":80,"minimum":1,"type":"integer"},{"type":"null"}],"default":30,"description":"Maximum records to return (default 30, max 80).","title":"Limit"},"skip":{"anyOf":[{"minimum":0,"type":"integer"},{"type":"null"}],"default":0,"description":"Number of records to skip, for paging (default 0).","title":"Skip"}},"required":["cohort_id"],"title":"get_recent_cohort_measurementsArguments","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_daily_forecast":{"post":{"operationId":"get_daily_forecast","summary":"Get the 7-day PM2.5 forecast for one site with AQI category, health advice and weather context (needs the Premium plan).","description":"Get the 7-day PM2.5 forecast for one site with AQI category, health advice and weather context (needs the Premium plan). Use for \"How will air quality be at site 64f7b3e8c9d25a0013f2d456 this week\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"site_id":{"description":"Site id from list_sites.","maxLength":200,"title":"Site Id","type":"string"}},"required":["site_id"],"title":"get_daily_forecastArguments","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_coverage_countries":{"post":{"operationId":"list_coverage_countries","summary":"Pan-African registry of air quality monitors from any operator: list countries with monitor counts by type (reference or","description":"Pan-African registry of air quality monitors from any operator: list countries with monitor counts by type (reference or low-cost) and status. Use for \"How many air quality monitors does each African country have\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"active_only":{"anyOf":[{"type":"boolean"},{"type":"null"}],"default":false,"description":"True to leave out monitors whose status is inactive.","title":"Active Only"},"types":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}],"default":null,"description":"Comma-separated monitor types to keep: Reference and/or LCS (low-cost sensor); omit for both.","title":"Types"},"network":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}],"default":null,"description":"Comma-separated network or operator names to keep.","title":"Network"}},"title":"list_coverage_countriesArguments","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_country_monitors":{"post":{"operationId":"list_country_monitors","summary":"List the monitors of one African country from the registry with type, status, operator, equipment, pollutants, resolutio","description":"List the monitors of one African country from the registry with type, status, operator, equipment, pollutants, resolution and uptime. Use for \"Which air quality monitors exist in Uganda\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"country_id":{"description":"Country id (slug) from list_coverage_countries, for example uganda.","maxLength":200,"title":"Country Id","type":"string"},"active_only":{"anyOf":[{"type":"boolean"},{"type":"null"}],"default":false,"description":"True to leave out monitors whose status is inactive.","title":"Active Only"},"types":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}],"default":null,"description":"Comma-separated monitor types to keep: Reference and/or LCS (low-cost sensor); omit for both.","title":"Types"},"network":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}],"default":null,"description":"Comma-separated network or operator names to keep.","title":"Network"}},"required":["country_id"],"title":"list_country_monitorsArguments","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_coverage_impact":{"post":{"operationId":"get_coverage_impact","summary":"Get aggregate registry statistics: total monitors by type and status, number of cities and countries covered and estimat","description":"Get aggregate registry statistics: total monitors by type and status, number of cities and countries covered and estimated population reached. Use for \"How big is the African air quality monitoring network\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"active_only":{"anyOf":[{"type":"boolean"},{"type":"null"}],"default":false,"description":"True to leave out monitors whose status is inactive.","title":"Active Only"},"types":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}],"default":null,"description":"Comma-separated monitor types to keep: Reference and/or LCS (low-cost sensor); omit for both.","title":"Types"},"network":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}],"default":null,"description":"Comma-separated network or operator names to keep.","title":"Network"}},"title":"get_coverage_impactArguments","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}}}}