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. |