Wherebox
Get API key

Generated from code

On this page

Configuration

Environment variables read by the server and tools. Variables marked secret hold credentials: never log them or put them in URLs. Empty values count as unset.

Server#

Variable Default Secret Description
PORT 8080 HTTP port of the API.
HOST 0.0.0.0 Interface to listen on.
LOG_LEVEL info Log level (fatal, error, warn, info, debug, trace).
WHEREBOX_PUBLIC_URL derived from the request Public base URL used for url in JSON responses (e.g. https://maps.example.com).
WHEREBOX_RENDER_CONCURRENCY CPUs − 1 Renders running at the same time per process.
WHEREBOX_MAP_REUSE 300 Renders per pooled MapLibre instance before it is recycled (bounds native memory).
WHEREBOX_METRICS_TOKEN (metrics disabled) secret Bearer token for the Prometheus endpoint /metrics; unset keeps it disabled. Scrape with Authorization: Bearer <token>.
WHEREBOX_RENDER_QUEUE 64 Renders waiting beyond the concurrency limit; more get 503 with Retry-After.
WHEREBOX_SITE_URL — Base URL of the website that hosts the playground page (e.g. https://wherebox.dev). When set, /playground redirects to <base>/playground/, which must route /v1/* to this API on the same origin. Unset: this server serves its own standalone playground.
WHEREBOX_TRUST_PROXY (no proxy trusted) Reverse proxies allowed to set the client address through X-Forwarded-For (and the protocol and host through X-Forwarded-Proto/-Host): addresses or CIDRs separated by commas, e.g. 127.0.0.1 for Caddy on the same machine, or loopback. Unset, the socket peer is the client, and a spoofed X-Forwarded-For is ignored. Behind a proxy, set it: otherwise every visitor has the proxy's address and all per-IP limits (anonymous allowance, sign-in emails, OAuth client registration) become one shared bucket. Never list addresses that untrusted clients can connect from.
WHEREBOX_DOCS_URL https://wherebox.dev/docs Base URL of the published docs. Problem type URIs point at <base>/errors#<code>; set it to serve your own copy of the docs (the code after # stays the same).

Data#

Variable Default Secret Description
DATABASE_URL postgres:///wherebox secret PostGIS database with the imported areas, places and countries. Country-level areas fall back to Natural Earth (the countries table) when the OSM import does not cover them.

Cache#

Variable Default Secret Description
WHEREBOX_GEOMETRY_CACHE 256 Area/subdivision geometries kept in memory (LRU; 0 = off). Cleared when the data version changes.
WHEREBOX_CACHE disk Rendered-image cache: disk, s3 (S3/R2/MinIO) or none.
WHEREBOX_IMAGE_CACHE_DIR data/cache/images Directory for the disk image cache.
WHEREBOX_IMAGE_CACHE_MAX_MB 2048 Disk image cache cap; least-recently-used images are evicted (0 = unlimited).
WHEREBOX_TILE_TTL_HOURS 720 After this many hours cached tiles, glyphs and terrain are revalidated in the background (stale ones keep serving).
WHEREBOX_STYLE_TTL_HOURS 24 Revalidation age for cached styles, TileJSON and sprites, so basemap updates show up.
WHEREBOX_CACHE_DIR data/cache/http Cache for basemap styles, tiles, glyphs and terrain.
WHEREBOX_S3_BUCKET — Bucket for WHEREBOX_CACHE=s3 (credentials via the standard AWS variables).
WHEREBOX_S3_PREFIX maps/ Key prefix inside the bucket.
WHEREBOX_S3_ENDPOINT AWS Endpoint for S3-compatible stores (R2, MinIO).
WHEREBOX_S3_REGION auto Region for the S3 client.

Routing#

Variable Default Secret Description
WHEREBOX_ROUTING_PROVIDER valhalla Default routing provider: valhalla, openrouteservice or graphhopper.
WHEREBOX_VALHALLA_URL (routing disabled) Valhalla server for car/bike/foot routes. Self-host it for production; the public FOSSGIS instance is for development only.
WHEREBOX_ORS_KEY — secret Server-side openrouteservice key (callers can send X-Routing-Key instead).
WHEREBOX_ORS_URL https://api.heigit.org/openrouteservice openrouteservice base URL (HeiGIT's hosted API; the old api.openrouteservice.org was shut off in Nov 2026). For a self-hosted openrouteservice, its base URL without /v2.
WHEREBOX_GRAPHHOPPER_KEY — secret Server-side GraphHopper key.
WHEREBOX_GRAPHHOPPER_URL https://graphhopper.com/api/1 GraphHopper base URL.
WHEREBOX_ROUTING_TIMEOUT_MS 10000 Timeout for routing requests.

Geocoding#

Variable Default Secret Description
WHEREBOX_GEOCODER_URL (fallback disabled) Geocoder for place names the imported OSM data does not know (place: points and route ends). Query parameters in the URL (e.g. ?key=…) are kept on every request and never appear in errors. Self-host Nominatim or Photon for production; the public instances allow about 1 request/s and are for development only.
WHEREBOX_GEOCODER_PROVIDER nominatim API flavour of WHEREBOX_GEOCODER_URL: nominatim (also LocationIQ and other Nominatim-compatible services) or photon.
WHEREBOX_GEOCODER_USER_AGENT wherebox (self-hosted static map renderer) User-Agent sent to the geocoder. Public Nominatim requires one that identifies your application.
WHEREBOX_GEOCODER_RPS 1 Maximum geocoder requests per second per process (0 = unlimited). Results are cached, so repeated names cost nothing.
WHEREBOX_GEOCODER_TIMEOUT_MS 5000 Timeout per lookup, including time spent waiting for a rate-limit slot.

Remote assets (security)#

Variable Default Secret Description
WHEREBOX_AUTH none API access: none (open, for self-hosting) or keys (API keys, signed URLs, rate limits, quotas, usage metering).
WHEREBOX_AUTH_SECRET (required with keys) secret Master secret (≥ 32 chars) for key hashing and URL-signing secrets. Changing it invalidates all keys.
WHEREBOX_PLANS built-in free/plus/internal JSON plan definitions replacing the built-in ones: {"free": {"monthlyRenders": 10000, "monthlyRoutedRenders": 1000, "perMinute": 60, "maxPixels": 4194304, "routing": true}, …}. Limits apply per account; 0 means unlimited. New accounts get free. The anonymous plan (built-in unless given here) sets the demo allowance for requests without a key, per client network, with dailyRenders (new renders per UTC day) instead of a monthly quota.
WHEREBOX_ANONYMOUS on With WHEREBOX_AUTH=keys: on gives requests without any key a small demo allowance (GET maps and searches only, limits from the anonymous plan, per IPv4 address or IPv6 /64, counted in memory and reset at midnight UTC), so a public playground and docs work without signing up; off makes every request need a key. A malformed or unknown key is always refused, never treated as anonymous. Set WHEREBOX_TRUST_PROXY behind a reverse proxy, or all visitors share one allowance.
WHEREBOX_ANONYMOUS_DAILY_CAP 2000 New renders per UTC day for all anonymous clients together (0 = no cap), so many addresses cannot turn the demo allowance into free bulk rendering. Cache hits do not count.
WHEREBOX_MORE_USAGE_URL (none) Page explaining how to ask for higher limits, linked from quota and plan-limit errors (the hosted service uses its fair-use page, https://wherebox.dev/docs/guides/fair-use/#need-more).
WHEREBOX_CONTACT_EMAIL (none) Address for limit requests (hosted: [email protected]). The Usage page opens an email to it with the account details filled in; without it, the page links to WHEREBOX_MORE_USAGE_URL.
WHEREBOX_GITHUB_CLIENT_ID (GitHub sign-in off) Client ID of the GitHub OAuth app for "Continue with GitHub" in the console (WHEREBOX_AUTH=keys). Its callback URL is <WHEREBOX_PUBLIC_URL>/auth/github/callback.
WHEREBOX_GITHUB_CLIENT_SECRET (GitHub sign-in off) secret Client secret of that GitHub OAuth app; set both or neither.
WHEREBOX_RESEND_API_KEY (links printed to stdout) secret Resend API key for magic-link sign-in emails. Unset, sign-in links are printed to the log, which is allowed only when the public URL is http://localhost.
WHEREBOX_MAIL_FROM — Sender of sign-in emails, e.g. Wherebox <[email protected]> (a domain verified in Resend). Required with WHEREBOX_RESEND_API_KEY.
WHEREBOX_STRIPE_SECRET_KEY (billing off) secret Stripe secret (or restricted) API key for the console billing pages. Billing is on only when this, WHEREBOX_STRIPE_WEBHOOK_SECRET and WHEREBOX_STRIPE_PRICES are all set.
WHEREBOX_STRIPE_WEBHOOK_SECRET (billing off) secret Signing secret (whsec_…) of the Stripe webhook endpoint <WHEREBOX_PUBLIC_URL>/webhooks/stripe; every webhook is verified with it.
WHEREBOX_STRIPE_PRICES (billing off) JSON mapping plan id to Stripe price id, e.g. {"plus":"price_…"}. Each plan must exist in the plans config (WHEREBOX_PLANS or the built-in ones).
WHEREBOX_ICON_HOSTS (remote icons disabled) Comma-separated hosts allowed for remote marker icons (*.example.com matches subdomains). Empty = data: URIs only.
WHEREBOX_ICON_MAX_BYTES 100000 Maximum icon size.
WHEREBOX_ICON_TIMEOUT_MS 5000 Timeout for fetching a remote icon.
WHEREBOX_FONT_HOSTS same as WHEREBOX_ICON_HOSTS Hosts allowed for custom font URLs.
WHEREBOX_FONT_MAX_BYTES 3000000 Maximum custom font size.
WHEREBOX_FONT_TIMEOUT_MS 8000 Timeout for fetching a custom font.

Import tools#

Variable Default Secret Description
WORK_DIR data/work Scratch directory for the OSM and Natural Earth imports.
NE_WORLDVIEWS all Natural Earth worldviews imported by pnpm import:countries for the worldview parameter: all, none, or codes such as in cn ma (about 13 MB download each). Border lines for all worldviews are always imported; this picks the country shapes.
NE_VERSION v5.1.2 Natural Earth release used by pnpm import:countries (pinned for reproducible renders).

Deployment#

Variable Default Secret Description
WHEREBOX_DOMAIN localhost Public domain for Caddy (TLS) in docker-compose.

Debugging#

Variable Default Secret Description
WHEREBOX_DEBUG — Set to log MapLibre Native errors.

Local MCP server (npx @wherebox/mcp)#

Variable Default Secret Description
WHEREBOX_API_URL https://api.wherebox.dev Wherebox API the local MCP server calls: the hosted service, or your own server (e.g. http://localhost:8080).
WHEREBOX_API_KEY (none: only for servers without keys) secret Secret key (sk_…) the local MCP server sends as Authorization: Bearer. Required for the hosted service; leave unset for a self-hosted server with WHEREBOX_AUTH=none.