Welcome! This is a docs-only first issue — a great way to learn how darkmap's data plumbing works while producing something every future contributor will use. darkmap proxies a handful of open datasets, but there's no single doc that explains how to get set up with the one API key we need, what's free, and how to add or contribute back to an upstream. Let's write one (the repo has no CONTRIBUTING.md yet).
What to cover:
-
The one key we need — OpenAQ. darkmap holds exactly one runtime secret: OPENAQ_API_KEY. Document how to get a free key (https://openaq.org), where it goes locally (copy .env.example → .env; the var is stubbed there), and the soft-degrade behavior: without it, /api/atmospheric/openaq returns an empty FeatureCollection with degraded: true rather than erroring (see emptyDegraded() in src/routes/api/atmospheric/openaq/+server.ts). AGENTS.md §Secrets is the authoritative source for the production story — link to it, don't restate the k8s details.
-
The keyless upstreams — Open-Meteo. Document that Open-Meteo is free, no key, CC-BY 4.0, used for the point forecast (src/routes/api/atmospheric/point/+server.ts) and CAMS air-quality/pollen (src/routes/api/atmospheric/airquality/+server.ts). Note the honesty rule: a missing value is rendered "none reported," never coerced to 0.
-
The other proxies (one line each), with upstream + license:
- Light/atmospheric raster → GeoServer + NASA GIBS via
src/routes/api/raster/+server.ts
- Elevation → AWS Terrarium tiles, public S3, no auth (
src/routes/api/elevation/+server.ts)
- Geocoding → Photon (
https://photon.komoot.io/api) via src/lib/server/geocoder/GeocoderClient.ts
- Orbit/TLE → Celestrak, public-domain, cached 2 h with a polite-use note (
src/routes/api/orbit/tle/+server.ts)
-
How to add/extend an upstream. Short recipe: add a +server.ts under src/routes/api/..., validate params + error(4xx) on bad input, hold any secret server-side via $env/dynamic/private (pattern: const apiKey = env.OPENAQ_API_KEY), set sensible cache-control, prefer soft-degrade over hard error for optional data.
-
Contributing back to the open datasets. A friendly paragraph: OpenAQ accepts community data and is CC-BY; Open-Meteo/CAMS and Celestrak are public goods — link their contribution/attribution pages so users know darkmap is built on (and gives back to) open data.
Files to look at:
.env.example (the OPENAQ_API_KEY stub)
AGENTS.md §Secrets
src/routes/api/atmospheric/{openaq,point,airquality}/+server.ts
src/routes/api/{elevation,geocode}/+server.ts, src/lib/server/geocoder/GeocoderClient.ts, src/routes/api/orbit/tle/+server.ts
README.md §Privacy (the "proxied only to normalize responses and caching" framing)
Acceptance criteria:
How to verify it's safe: docs-only. just check stays green. A maintainer follows the OpenAQ steps from scratch and confirms the smog overlay lights up with a fresh key (and degrades cleanly without one).
Welcome! This is a docs-only first issue — a great way to learn how darkmap's data plumbing works while producing something every future contributor will use. darkmap proxies a handful of open datasets, but there's no single doc that explains how to get set up with the one API key we need, what's free, and how to add or contribute back to an upstream. Let's write one (the repo has no
CONTRIBUTING.mdyet).What to cover:
The one key we need — OpenAQ. darkmap holds exactly one runtime secret:
OPENAQ_API_KEY. Document how to get a free key (https://openaq.org), where it goes locally (copy.env.example→.env; the var is stubbed there), and the soft-degrade behavior: without it,/api/atmospheric/openaqreturns an emptyFeatureCollectionwithdegraded: truerather than erroring (seeemptyDegraded()insrc/routes/api/atmospheric/openaq/+server.ts).AGENTS.md§Secrets is the authoritative source for the production story — link to it, don't restate the k8s details.The keyless upstreams — Open-Meteo. Document that Open-Meteo is free, no key, CC-BY 4.0, used for the point forecast (
src/routes/api/atmospheric/point/+server.ts) and CAMS air-quality/pollen (src/routes/api/atmospheric/airquality/+server.ts). Note the honesty rule: a missing value is rendered "none reported," never coerced to 0.The other proxies (one line each), with upstream + license:
src/routes/api/raster/+server.tssrc/routes/api/elevation/+server.ts)https://photon.komoot.io/api) viasrc/lib/server/geocoder/GeocoderClient.tssrc/routes/api/orbit/tle/+server.ts)How to add/extend an upstream. Short recipe: add a
+server.tsundersrc/routes/api/..., validate params +error(4xx)on bad input, hold any secret server-side via$env/dynamic/private(pattern:const apiKey = env.OPENAQ_API_KEY), set sensiblecache-control, prefer soft-degrade over hard error for optional data.Contributing back to the open datasets. A friendly paragraph: OpenAQ accepts community data and is CC-BY; Open-Meteo/CAMS and Celestrak are public goods — link their contribution/attribution pages so users know darkmap is built on (and gives back to) open data.
Files to look at:
.env.example(theOPENAQ_API_KEYstub)AGENTS.md§Secretssrc/routes/api/atmospheric/{openaq,point,airquality}/+server.tssrc/routes/api/{elevation,geocode}/+server.ts,src/lib/server/geocoder/GeocoderClient.ts,src/routes/api/orbit/tle/+server.tsREADME.md§Privacy (the "proxied only to normalize responses and caching" framing)Acceptance criteria:
CONTRIBUTING.md(ordocs/UPSTREAMS.md) covering all five sections..env.example→.env, free key URL) and the degrade behavior is described so a keyless contributor isn't confused by an "empty" smog layer.How to verify it's safe: docs-only.
just checkstays green. A maintainer follows the OpenAQ steps from scratch and confirms the smog overlay lights up with a fresh key (and degrades cleanly without one).