feat: implement docs-site, legal docs, metrics standard, flux manifests
Closes leeworks-agents/api-company#5 (docs-site Astro scaffold) Closes leeworks-agents/api-company#9 (metrics instrumentation standard) Closes leeworks-agents/api-company#10 (Gitea Actions openapi aggregation pipeline) Closes leeworks-agents/api-company#11 (docs-site Flux HelmRelease) Closes leeworks-agents/api-company#12 (SEO blog posts x3) Closes leeworks-agents/api-company#13 (legal docs ToS/Privacy/AUP) Closes leeworks-agents/api-company#14 (DNS documentation) ## Changes ### docs/legal/ - terms-of-service.md — API usage, liability, account termination, governing law - privacy-policy.md — request log retention (90d), no PII sold, data sharing - acceptable-use-policy.md — rate limit abuse, scraping prohibition, resale ban ### docs/metrics-standard.md - Defines api_requests_total, api_response_duration_seconds, api_data_freshness_seconds - Fastify (TypeScript) and FastAPI (Python) reference middleware implementations - Prometheus scrape config and Grafana dashboard guidance ### docs/registry.md - Decision: use Gitea built-in container registry (no new infra) - Image naming convention, auth, Kubernetes imagePullSecrets, ingress config ### docs/dns.md - Required A records for all 6 subdomains - cert-manager ClusterIssuer and Ingress TLS examples - Verification commands and human-operator action items ### docs-site/ - Astro 4 + MDX + sitemap scaffold - Base layout with nav linking all APIs, blog, RapidAPI, status - Landing page with API cards - Per-API Redoc viewer pages (zip-enrichment, holidays, air-quality) - Blog index + 3 SEO blog posts (~1000 words each with JSON-LD) - Dockerfile (multi-stage: node build + nginx serve) - nginx.conf with gzip, caching, health endpoint ### flux/ - gitea-runner/: gitea-act-runner HelmRelease (org-scope, dind) - monitoring/: kube-prometheus-stack + Gatus HelmReleases - Prometheus with pod annotation scraping - Grafana at grafana.leeworks.dev with persistence - Gatus status page at status.leeworks.dev, 90-day retention - docs-site/: Deployment + Service + Ingress via raw chart - api-company-source/: GitRepository + Kustomization reference manifests - kustomization.yaml: root kustomize entry point (build validated) ### .gitea/workflows/build-docs.yaml - Aggregates openapi.yaml from zip-enrichment, holidays, air-quality repos - Builds Astro docs-site - Pushes image to registry.leeworks.dev/leeworks-agents/docs-site - Triggered on push to main, schedule daily 02:00 UTC, workflow_dispatch
This commit is contained in:
@@ -0,0 +1,178 @@
|
||||
---
|
||||
title: "Air Quality API: Real-Time AQI Data for Any Location"
|
||||
description: "Access real-time Air Quality Index (AQI) data, PM2.5, PM10, and health recommendations for any city worldwide using the leeworks.dev Air Quality API."
|
||||
date: "2026-05-24"
|
||||
author: "leeworks.dev"
|
||||
tags: ["air-quality", "aqi", "api", "tutorial"]
|
||||
---
|
||||
|
||||
import Base from '../../layouts/Base.astro';
|
||||
|
||||
<Base title="Air Quality API Guide" description="Access real-time AQI data for any location worldwide.">
|
||||
|
||||
<article style="max-width: 800px; margin: 0 auto; padding: 2rem; line-height: 1.75;">
|
||||
|
||||
<script type="application/ld+json" set:html={JSON.stringify({
|
||||
"@context": "https://schema.org",
|
||||
"@type": "Article",
|
||||
"headline": "Air Quality API: Real-Time AQI Data for Any Location",
|
||||
"datePublished": "2026-05-24",
|
||||
"author": { "@type": "Organization", "name": "leeworks.dev" },
|
||||
"publisher": { "@type": "Organization", "name": "leeworks.dev", "url": "https://docs.leeworks.dev" }
|
||||
})} />
|
||||
|
||||
# Air Quality API: Real-Time AQI Data for Any Location
|
||||
|
||||
Whether you're building a fitness app, a travel planner, or a smart home dashboard, air quality data is increasingly essential. The leeworks.dev **Air Quality API** gives you real-time AQI readings, pollutant breakdowns, and health recommendations for any location in the world.
|
||||
|
||||
## What Is AQI and Why Does Your App Need It?
|
||||
|
||||
The **Air Quality Index (AQI)** is a standardized scale (0–500) that communicates how clean or polluted the air is:
|
||||
|
||||
| AQI | Category | Health Implication |
|
||||
|-----|----------|-------------------|
|
||||
| 0–50 | Good | Air quality is satisfactory |
|
||||
| 51–100 | Moderate | Acceptable for most people |
|
||||
| 101–150 | Unhealthy for Sensitive Groups | At-risk groups may experience effects |
|
||||
| 151–200 | Unhealthy | Everyone may begin to experience health effects |
|
||||
| 201–300 | Very Unhealthy | Health alert: serious effects possible |
|
||||
| 301–500 | Hazardous | Emergency conditions |
|
||||
|
||||
**Use cases for an AQI data API:**
|
||||
|
||||
- **Fitness apps** — warn runners when outdoor exercise is unsafe
|
||||
- **Travel apps** — show air quality forecasts for destination cities
|
||||
- **Real estate platforms** — display neighborhood air quality scores
|
||||
- **Smart home apps** — trigger air purifiers based on outdoor AQI
|
||||
- **Health tracking apps** — correlate symptoms with air quality data
|
||||
- **News and weather apps** — add AQI to daily weather cards
|
||||
|
||||
## Quick Start
|
||||
|
||||
```bash
|
||||
# Get current AQI for a city
|
||||
curl "https://aqi.leeworks.dev/v1/current?city=Los+Angeles&country=US" \
|
||||
-H "X-RapidAPI-Key: YOUR_API_KEY"
|
||||
```
|
||||
|
||||
Response:
|
||||
```json
|
||||
{
|
||||
"location": {
|
||||
"city": "Los Angeles",
|
||||
"country": "US",
|
||||
"latitude": 34.0522,
|
||||
"longitude": -118.2437
|
||||
},
|
||||
"aqi": 87,
|
||||
"category": "Moderate",
|
||||
"pollutants": {
|
||||
"pm25": 22.4,
|
||||
"pm10": 35.1,
|
||||
"o3": 41.2,
|
||||
"no2": 18.5,
|
||||
"so2": 2.1,
|
||||
"co": 0.4
|
||||
},
|
||||
"health_recommendation": "Unusually sensitive people should consider reducing prolonged outdoor exertion.",
|
||||
"updated_at": "2026-05-24T14:30:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
## By Coordinates (Lat/Long)
|
||||
|
||||
```bash
|
||||
curl "https://aqi.leeworks.dev/v1/current?lat=48.8566&lon=2.3522" \
|
||||
-H "X-RapidAPI-Key: YOUR_API_KEY"
|
||||
```
|
||||
|
||||
## Code Examples
|
||||
|
||||
### JavaScript
|
||||
|
||||
```javascript
|
||||
async function getAirQuality(city, country = 'US') {
|
||||
const response = await fetch(
|
||||
`https://aqi.leeworks.dev/v1/current?city=${encodeURIComponent(city)}&country=${country}`,
|
||||
{ headers: { 'X-RapidAPI-Key': process.env.RAPIDAPI_KEY } }
|
||||
);
|
||||
return response.json();
|
||||
}
|
||||
|
||||
const data = await getAirQuality('Denver');
|
||||
if (data.aqi > 100) {
|
||||
console.warn(`Air quality in ${data.location.city} is ${data.category}. Consider staying indoors.`);
|
||||
}
|
||||
```
|
||||
|
||||
### Python
|
||||
|
||||
```python
|
||||
import httpx
|
||||
|
||||
def get_aqi(lat: float, lon: float) -> dict:
|
||||
resp = httpx.get(
|
||||
"https://aqi.leeworks.dev/v1/current",
|
||||
params={"lat": lat, "lon": lon},
|
||||
headers={"X-RapidAPI-Key": "YOUR_KEY"},
|
||||
)
|
||||
resp.raise_for_status()
|
||||
return resp.json()
|
||||
|
||||
# Example: check AQI before recommending outdoor run
|
||||
aqi_data = get_aqi(37.7749, -122.4194) # San Francisco
|
||||
if aqi_data["aqi"] <= 100:
|
||||
print("Good to go for a run!")
|
||||
else:
|
||||
print(f"Air quality is {aqi_data['category']} — consider indoor exercise.")
|
||||
```
|
||||
|
||||
### React Hook
|
||||
|
||||
```tsx
|
||||
import { useState, useEffect } from 'react';
|
||||
|
||||
interface AQIData {
|
||||
aqi: number;
|
||||
category: string;
|
||||
health_recommendation: string;
|
||||
}
|
||||
|
||||
export function useAirQuality(city: string) {
|
||||
const [data, setData] = useState<AQIData | null>(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
fetch(`/api/aqi?city=${encodeURIComponent(city)}`)
|
||||
.then(r => r.json())
|
||||
.then(setData)
|
||||
.finally(() => setLoading(false));
|
||||
}, [city]);
|
||||
|
||||
return { data, loading };
|
||||
}
|
||||
```
|
||||
|
||||
## Data Source
|
||||
|
||||
The leeworks.dev Air Quality API aggregates data from the **OpenAQ** public dataset — a non-profit platform that collects open air quality data from government agencies worldwide. Data is refreshed hourly.
|
||||
|
||||
## Pricing
|
||||
|
||||
| Plan | Requests/mo | Price |
|
||||
|------|------------|-------|
|
||||
| Free | 500 | $0 |
|
||||
| Basic | 10,000 | $9/mo |
|
||||
| Pro | 100,000 | $19/mo |
|
||||
| Ultra | 1,000,000 | $49/mo |
|
||||
|
||||
**[Subscribe on RapidAPI →](https://rapidapi.com/leeworks/api/air-quality)**
|
||||
|
||||
## Conclusion
|
||||
|
||||
Air quality is no longer a niche data point — it's a critical health metric that millions of people check daily. The leeworks.dev **AQI data API** gives your app real-time air quality readings, pollutant breakdowns, and actionable health recommendations with a simple REST interface.
|
||||
|
||||
**[Start building for free →](https://rapidapi.com/leeworks/api/air-quality)**
|
||||
|
||||
</article>
|
||||
</Base>
|
||||
Reference in New Issue
Block a user