Skip to content

HTTP: GIBS proxy route

This is the only server-side route in the app. It fetches one full-globe equirectangular WMS snapshot from NASA GIBS and returns it with long CDN cache headers, keyed by layer and date. It holds no secrets; it exists to protect the upstream and speed up users.

GET /api/gibs/{layer}?date=YYYY-MM-DD
Name Type Description
layer string A known layer slug (for example blue-marble). Unknown slugs return 404.
Name Type Default Description
date YYYY-MM-DD most recent available day The imagery day. Must match the date format.

An image (image/jpeg or image/png) with these headers:

Header Example Meaning
Content-Type image/jpeg The image format from GIBS.
Cache-Control public, s-maxage=86400, stale-while-revalidate=172800 One imagery day is immutable once published, so it caches hard.
X-Gibs-Layer MODIS_Terra_CorrectedReflectance_TrueColor The upstream GIBS layer id served.
X-Gibs-Date 2026-07-22 The day actually served (may differ from the request after fallback).
Status Body When
400 Bad Request { "error": "date must be YYYY-MM-DD" } The date parameter is malformed.
404 Not Found { "error": "Unknown layer \"...\"" } The layer slug is not recognised.
5xx { "error": "..." } Every fallback day failed upstream. The message names the last upstream error.
Terminal window
# Most recent available imagery for a layer
curl -i "https://your-deploy.vercel.app/api/gibs/blue-marble"
# A specific day
curl -i "https://your-deploy.vercel.app/api/gibs/blue-marble?date=2026-07-01"
# Inspect which day was actually served
curl -sI "https://your-deploy.vercel.app/api/gibs/blue-marble" | grep -i x-gibs-date

Fetching full-globe tiles directly from GIBS on every page load would be slow and would hammer a shared public service. This route adds a CDN cache keyed by layer and date, so each day is fetched once and served from the edge thereafter. See The compute decision for where this fits.