> ## Documentation Index
> Fetch the complete documentation index at: https://www.worldmonitor.app/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Relay Parameters (Railway + Vercel)

> Every environment variable used by the AIS and OpenSky relay path — Railway + Vercel deployment envs, timeouts, and upstream credential wiring.

This document covers all environment variables used by the AIS/OpenSky relay path:

* Railway relay process: `scripts/ais-relay.cjs`
* Vercel relay proxy endpoints (legacy): `api/opensky.js`, `api/ais-snapshot.js`, `api/polymarket.js`, `api/rss-proxy.js`

<Note>
  The `api/*.js` edge function endpoints listed above are legacy patterns being phased out in favor of the sebuf proto-first approach. See [Adding Endpoints](/docs/adding-endpoints) for the current recommended pattern.
</Note>

* Server relay callers: `server/worldmonitor/*` handlers
* Optional browser local fallback callers in `src/services/*`

## 1) Minimum Production Setup

Set these before enabling strict relay auth.

### Railway (relay)

| Variable              | Required    | Example             | Notes                                      |
| --------------------- | ----------- | ------------------- | ------------------------------------------ |
| `AISSTREAM_API_KEY`   | Yes         | `ais_...`           | Required for AIS upstream WebSocket feed.  |
| `RELAY_SHARED_SECRET` | Yes         | `wm_relay_prod_...` | Must exactly match Vercel value.           |
| `RELAY_AUTH_HEADER`   | Recommended | `x-relay-key`       | Must match Vercel if changed from default. |

### Vercel (proxy + server functions)

| Variable              | Required    | Example                                | Notes                                                 |
| --------------------- | ----------- | -------------------------------------- | ----------------------------------------------------- |
| `WS_RELAY_URL`        | Yes         | `https://<railway-app>.up.railway.app` | HTTPS relay base URL used by server-side proxy calls. |
| `RELAY_SHARED_SECRET` | Yes         | `wm_relay_prod_...`                    | Must exactly match Railway value.                     |
| `RELAY_AUTH_HEADER`   | Recommended | `x-relay-key`                          | Header name used to forward relay secret.             |

## 2) Full Parameter Reference

## Core Relay/Auth

| Variable                          | Set On                         | Default       | Required                        | Purpose                                                                                                                                                                                                        |
| --------------------------------- | ------------------------------ | ------------- | ------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `AISSTREAM_API_KEY`               | Railway                        | none          | Yes                             | Auth for AIS upstream stream source.                                                                                                                                                                           |
| `VITE_AISSTREAM_API_KEY`          | Local dev only                 | none          | No                              | Local fallback if `AISSTREAM_API_KEY` is missing. Not recommended for production.                                                                                                                              |
| `PORT`                            | Railway/local                  | `3004`        | No                              | HTTP server listen port for relay process.                                                                                                                                                                     |
| `WS_RELAY_URL`                    | Vercel + server handlers       | none          | Yes (for relay-backed features) | Base URL used by Vercel/server to reach Railway relay.                                                                                                                                                         |
| `VITE_WS_RELAY_URL`               | Browser (local dev)            | none          | No                              | Localhost fallback path for direct browser calls in development only.                                                                                                                                          |
| `RELAY_SHARED_SECRET`             | Railway + Vercel + self-hosted | empty         | **Yes (always)**                | Shared secret for non-public relay routes. The relay refuses to start without it unless `I_UNDERSTAND_THIS_DISABLES_AUTH=true`.                                                                                |
| `RELAY_AUTH_HEADER`               | Railway + Vercel               | `x-relay-key` | No (but recommended explicit)   | Header name carrying relay secret.                                                                                                                                                                             |
| `I_UNDERSTAND_THIS_DISABLES_AUTH` | Railway / self-hosted          | `false`       | No                              | Dev-only escape hatch. If `true`, the relay boots WITHOUT a shared secret, logs a loud `[SECURITY]` line at boot and every 5 minutes, and accepts every request on non-public routes. Never set in production. |
| `ALLOW_UNAUTHENTICATED_RELAY`     | Railway / self-hosted          | `false`       | No                              | **Deprecated** alias of `I_UNDERSTAND_THIS_DISABLES_AUTH`. Still accepted for back-compat; the relay logs a `[DEPRECATED]` warning when this name is used.                                                     |
| `ALLOW_VERCEL_PREVIEW_ORIGINS`    | Railway                        | `false`       | No                              | If `true`, allows `*.vercel.app` origins in relay CORS checks.                                                                                                                                                 |

## Relay-Adjacent Feature Flags

| Variable           | Set On                   | Default                  | Required | Purpose                                                                                   |
| ------------------ | ------------------------ | ------------------------ | -------- | ----------------------------------------------------------------------------------------- |
| `VITE_ENABLE_AIS`  | Browser/client build env | enabled (unless `false`) | No       | Client-side feature gate for AIS UI/polling.                                              |
| `LOCAL_API_MODE`   | Local/server runtime     | none                     | No       | If contains `sidecar`, some server handlers bypass relay and call OpenSky directly.       |
| `WINGBITS_API_KEY` | Vercel/server            | none                     | No       | Military enrichment/fallback source used by server handlers; not required for relay core. |

## OpenSky Upstream Auth

| Variable                | Set On  | Default | Required         | Purpose                                                     |
| ----------------------- | ------- | ------- | ---------------- | ----------------------------------------------------------- |
| `OPENSKY_CLIENT_ID`     | Railway | none    | No (recommended) | OAuth client ID for higher OpenSky reliability/rate limits. |
| `OPENSKY_CLIENT_SECRET` | Railway | none    | No (recommended) | OAuth client secret paired with client ID.                  |

## OpenSky Cache/Cardinality Controls

| Variable                             | Set On  | Default | Required | Purpose                                                                           |
| ------------------------------------ | ------- | ------- | -------- | --------------------------------------------------------------------------------- |
| `OPENSKY_CACHE_MAX_ENTRIES`          | Railway | `128`   | No       | Max positive cache keys retained in memory.                                       |
| `OPENSKY_NEGATIVE_CACHE_MAX_ENTRIES` | Railway | `256`   | No       | Max negative cache keys (`429/5xx`) retained in memory.                           |
| `OPENSKY_BBOX_QUANT_STEP`            | Railway | `0.01`  | No       | Coordinate quantization step for bbox cache key reuse. `0` disables quantization. |

## AIS Pipeline Tuning

| Variable                        | Set On  | Default                            | Required | Purpose                                                    |
| ------------------------------- | ------- | ---------------------------------- | -------- | ---------------------------------------------------------- |
| `AIS_SNAPSHOT_INTERVAL_MS`      | Railway | `5000` (min `2000`)                | No       | Interval for rebuilding snapshot payloads.                 |
| `AIS_UPSTREAM_QUEUE_HIGH_WATER` | Railway | `4000` (min `500`)                 | No       | Pause upstream socket when queue reaches this.             |
| `AIS_UPSTREAM_QUEUE_LOW_WATER`  | Railway | `1000` (clamped below HIGH\_WATER) | No       | Resume upstream socket when queue drops below this.        |
| `AIS_UPSTREAM_QUEUE_HARD_CAP`   | Railway | `8000` (must be `> HIGH_WATER`)    | No       | Max queue size before dropping incoming upstream messages. |
| `AIS_UPSTREAM_DRAIN_BATCH`      | Railway | `250` (min `1`)                    | No       | Max messages drained per cycle.                            |
| `AIS_UPSTREAM_DRAIN_BUDGET_MS`  | Railway | `20` (min `2`)                     | No       | Max CPU time budget per drain cycle.                       |

## Rate Limit / Logging / Metrics

| Variable                       | Set On  | Default         | Required | Purpose                                               |
| ------------------------------ | ------- | --------------- | -------- | ----------------------------------------------------- |
| `RELAY_RATE_LIMIT_WINDOW_MS`   | Railway | `60000`         | No       | Global rate-limit window.                             |
| `RELAY_RATE_LIMIT_MAX`         | Railway | `1200`          | No       | Default max requests per IP per window.               |
| `RELAY_OPENSKY_RATE_LIMIT_MAX` | Railway | `600`           | No       | OpenSky route max requests per IP per window.         |
| `RELAY_RSS_RATE_LIMIT_MAX`     | Railway | `300`           | No       | RSS route max requests per IP per window.             |
| `RELAY_LOG_THROTTLE_MS`        | Railway | `10000`         | No       | Minimum interval between repeated log events per key. |
| `RELAY_METRICS_WINDOW_SECONDS` | Railway | `60` (min `10`) | No       | Rolling window used by `/metrics`.                    |

## Platform-Managed Variables (Do Not Manually Set)

These are used only for production detection and are usually injected by platform/runtime.

| Variable              | Who sets it      | Purpose                                      |
| --------------------- | ---------------- | -------------------------------------------- |
| `NODE_ENV`            | Runtime/platform | Used to detect production mode.              |
| `RAILWAY_ENVIRONMENT` | Railway          | Used to detect production relay environment. |
| `RAILWAY_PROJECT_ID`  | Railway          | Used to detect production relay environment. |
| `RAILWAY_STATIC_URL`  | Railway          | Used to detect production relay environment. |

## 3) Recommended Starting Values (High Traffic Baseline)

These are safe starting points for a busy relay:

```bash theme={null}
# Auth + routing — RELAY_SHARED_SECRET is REQUIRED (the relay exits at startup
# without it unless I_UNDERSTAND_THIS_DISABLES_AUTH=true is set).
RELAY_SHARED_SECRET=<strong-random-secret>   # openssl rand -hex 32
RELAY_AUTH_HEADER=x-relay-key
WS_RELAY_URL=https://<your-railway-relay>.up.railway.app
# I_UNDERSTAND_THIS_DISABLES_AUTH=false   # dev-only override; do NOT set in prod

# OpenSky cache/cardinality
OPENSKY_CACHE_MAX_ENTRIES=256
OPENSKY_NEGATIVE_CACHE_MAX_ENTRIES=512
OPENSKY_BBOX_QUANT_STEP=0.01

# AIS pipeline
AIS_SNAPSHOT_INTERVAL_MS=3000
AIS_UPSTREAM_QUEUE_HIGH_WATER=5000
AIS_UPSTREAM_QUEUE_LOW_WATER=1500
AIS_UPSTREAM_QUEUE_HARD_CAP=10000
AIS_UPSTREAM_DRAIN_BATCH=300
AIS_UPSTREAM_DRAIN_BUDGET_MS=20

# Rate limits + metrics
RELAY_RATE_LIMIT_WINDOW_MS=60000
RELAY_RATE_LIMIT_MAX=1200
RELAY_OPENSKY_RATE_LIMIT_MAX=600
RELAY_RSS_RATE_LIMIT_MAX=300
RELAY_LOG_THROTTLE_MS=10000
RELAY_METRICS_WINDOW_SECONDS=60
```

## 4) How to Verify Configuration

Health:

```bash theme={null}
curl -sS https://<relay>/health
```

Metrics (requires relay auth):

```bash theme={null}
curl -sS https://<relay>/metrics \
  -H "x-relay-key: $RELAY_SHARED_SECRET"
```

or:

```bash theme={null}
curl -sS https://<relay>/metrics \
  -H "Authorization: Bearer $RELAY_SHARED_SECRET"
```

Expected checks:

* `auth.enabled` is `true` in `/health` (canonical operator-visible flag — `true` only when a shared secret is configured AND the `I_UNDERSTAND_THIS_DISABLES_AUTH` bypass is NOT engaged). `auth.sharedSecretEnabled` is preserved for back-compat.
* `/metrics.opensky.hitRatio` is stable and high under load.
* `/metrics.ais.dropsPerSec` stays at `0` in normal operation.
* `/metrics.ais.queueMax` is comfortably below `AIS_UPSTREAM_QUEUE_HARD_CAP`.
