Zuletzt aktualisiert 2026-07-15
API-Referenz
Überblick
Diese Seite richtet sich an Entwickler und Betreiber, die meridian-APIs integrieren — Alltagsbesucher können sie überspringen. Alle API-Routen sind Next.js App Router Handler unter src/app/api/. Wetter und Geocode brauchen OPENWEATHER_API_KEY. Cron-Routen brauchen Authorization: Bearer CRON_SECRET. Admin-Routen brauchen authentifiziertes Admin-Session-Cookie (meridian_admin_session) nach Anmeldung unter /login, außer ALLOW_DEV_ADMIN_BYPASS greift in der Entwicklung.
GET /api/weather
Query: lat, lon, scope (current|hourly|daily|minutely), optional trigger, lang. Liefert Wetter-Payload plus fetchedAt, cacheHit, freshness, source, trigger, tokensUsed. X-Cache-Header spiegelt Cache-Schicht. Fehler: 400 invalid params, 404 location not found, 429 rate_limited, 502 upstream_error oder service_unavailable.
POST /api/weather/batch
Body: { cities: [{ lat, lon, scopes?: string[], id?, lang?, maxAgeMs?, trigger? }], trigger?, lang? }. Liefert { cities: [{ lat, lon, scopes: { scope: { data, meta } | { error } } }] }. Scopes sind pro Stadt, kein top-level Array. Rate-Limit 20 Anfragen/Minute pro IP. Genutzt von Dashboard- und Stadt-Detail-Hooks.
GET /api/weather/history
Query: lat, lon, optional from, to (ISO-Daten), limit. Liefert { summary, observations, forecasts: { hourly, daily } } aus weather_observations und weather_forecast_archive.
GET /api/geocode
Query: q (min. 2 Zeichen), optionale context-Parameter. Liefert normalisiertes Array: name, country, state, lat, lon, label. Upstream-Limit 5 Ergebnisse. In L2 mit geocode-Scope gecacht. Rate-Limit 60 Anfragen/Minute pro IP.
GET /api/recent-checks
Keine Parameter. Liefert { checks, source }, wobei source popular ist, wenn suchgetriggerte Zeilen existieren, oder empty wenn keine. Standard limit 20 aus location_weather_checks nach Suchvolumen (search_select und search_preview triggers). API hat keinen Showcase-Fallback — die Home-UI kann trotzdem Demo-Beliebte-Städte zeigen, wenn leer und SHOW_DEMO_POPULAR_SEARCHES an ist. Spalte In Ihrer Nähe nutzt diese Route nicht.
/api/subscriptions
GET ?clientId= — aktive Abonnements für Client auflisten. POST — anlegen { clientId, email, type, cityName?, cityLat?, cityLon?, frequency?, alertOnRain?, alertOnStorm?, alertPrefs? }. PATCH — alertPrefs auf city_alerts-Zeile aktualisieren { clientId, id, alertPrefs }. DELETE — Body { clientId, cityLat, cityLon, types[] }. Typen: newsletter, city_weekly, city_alerts.
GET /api/unsubscribe
Query: token (unsubscribe_token UUID). Deaktiviert Abonnement und liefert HTML-Bestätigung.
GET /api/alerts/[alertId]
Liefert normalisierte Warnung: id, senderName, event, start, end, description. Quelle: gecachter alert-Scope.
Cron-Routen
GET /api/cron/weekly-digests — wöchentliche Digest-E-Mails nach Abonnenten-E-Mail gruppieren und senden. GET /api/cron/weather-alerts — alertPrefs gegen OpenWeather, Open-Meteo und NWS-Feeds prüfen und Warn-E-Mails senden. Beide brauchen Bearer CRON_SECRET.
Admin-Routen
Nutzung und Config: GET /api/admin/usage; GET|PATCH /api/admin/config; Legacy PATCH /api/admin/settings { refreshIntervalMs }. Nutzer und Auth: GET|POST /api/admin/users; POST /api/admin/users/invite; GET /api/admin/me. Daten: GET /api/admin/checks; GET /api/admin/locations; GET|PATCH /api/admin/subscriptions; GET /api/admin/mailing-summary; GET /api/admin/analytics. Connectors: GET|PATCH /api/admin/connections; GET|PATCH /api/admin/openweather-key; GET|PATCH /api/admin/email-key. E-Mail-CMS: GET|POST|PATCH /api/admin/email-templates; POST /api/admin/email/test, /compose, /sync. AdSense: GET /api/admin/adsense/report; POST /api/admin/adsense/sync; OAuth GET /api/admin/adsense/oauth/start, /callback, /disconnect. CMS: GET|PATCH /api/admin/cms-pages. Alle brauchen meridian_admin_session außer Dev-Bypass.
Ads-Routen
GET /api/ads/config — { scriptEnabled, clientId, consentRequired }. GET /api/ads?placement=dashboard|hero|recent-checks|city-detail — Platzierungs-Config mit slotId wenn gesetzt. GET /api/ads/placeholder-bg — Hero-Lookup für Platzhalterflächen. App-Route GET /ads.txt — AdSense-Publisher-Zeile aus env. Aktive AdSlot-Platzierungen: dashboard, hero, city-detail. recent-checks-Slot-env existiert, Home hat keinen AdSlot.
Weitere öffentliche Routen
GET /api/platform/limits — öffentlicher Quota-Snapshot. POST /api/analytics/collect — First-Party-Analytics-Beacon. GET /api/location/region — IP/Region-Helfer. POST /api/weather/inaccurate-report — schlechte Daten melden. GET /api/weather/map-tile/[layer]/[z]/[x]/[y] — OSM-Hero-Overlay-Kacheln. Auth: POST /api/auth/login, /logout; POST /api/auth/forgot-password; POST /api/auth/reset-password/[token]; GET|POST /api/auth/invite/[token]; GET /api/auth/session.
Fehlerform
JSON-Fehler typischerweise { error: code, message: string }. ApiError-Codes u. a. invalid_request, service_unavailable, location_not_found, rate_limited, upstream_error, unauthorized, not_found, limit_reached.