Skip to main content
ShadowBroker aggregates data from many sources. Most require no credentials, but three external services need API keys to unlock their data layers.

Data sources overview

ServiceKey requiredData layerFree tier
AISStream.ioOptional — AIS_API_KEYReal-time vessel positions (ships layer empty without it)Yes
OpenSky NetworkOptional — OPENSKY_CLIENT_ID + OPENSKY_CLIENT_SECRETFlight gap-fill in Africa / Asia / LatAmYes (400 req/day)
LTA DataMallOptional — LTA_ACCOUNT_KEYSingapore CCTV traffic camerasYes
ADS-B Exchange (adsb.lol)NoGlobal commercial, military, and private flights
USGS EarthquakesNoReal-time earthquake feed
CelesTrakNoSatellite orbital elements (TLEs)
GDELT ProjectNoGeolocated news events
NominatimNoReverse geocoding
RainViewerNoWeather radar tiles
OpenMHzNoPublic radio scanner feeds
Yahoo FinanceNoDefense stocks and commodity prices

Setting up each key

AIS Stream (required for ships layer)

1

Create a free account

Go to aisstream.io and sign up for a free account. No credit card is required.
2

Generate a WebSocket API key

After logging in, navigate to your dashboard and create a new API key. Copy the key — you will only see it once.
3

Add the key to your environment

Set AIS_API_KEY in backend/.env or your Docker Compose environment:
backend/.env
AIS_API_KEY=your-key-here
4

Restart the backend

The AIS stream connects at startup. Restart the backend container for the key to take effect:
docker compose restart backend

OpenSky Network (optional — improves flight coverage)

OpenSky fills in flight data in regions where ADS-B Exchange has sparse coverage. Both the client ID and client secret must be set together.
1

Register on OpenSky Network

Create a free account at opensky-network.org. The free tier provides 400 API requests per day.
2

Create an OAuth2 application

In your OpenSky dashboard, navigate to APIOAuth2 Applications and create a new application. Note the client ID and client secret.
3

Add both keys to your environment

backend/.env
OPENSKY_CLIENT_ID=your-client-id
OPENSKY_CLIENT_SECRET=your-client-secret
4

Restart the backend

docker compose restart backend

LTA DataMall (optional — Singapore CCTV cameras)

1

Register for LTA DataMall access

Go to datamall.lta.gov.sg and request API access. LTA requires a brief registration form. The key is provided free of charge.
2

Add the key to your environment

backend/.env
LTA_ACCOUNT_KEY=your-lta-key
3

Restart the backend

docker compose restart backend

Managing keys via the Settings panel

You can view and update API keys through the Settings panel in the dashboard UI without restarting the backend. Keys are written to backend/.env and take effect immediately in the running process.
  1. Open the dashboard and click Settings in the sidebar.
  2. Navigate to the API Keys tab.
  3. Click the edit icon next to any key.
  4. Enter the new value and click Save.
The Settings panel shows obfuscated key values — the first four characters followed by bullets. It never exposes the full key.

The /api/settings/api-keys endpoint

You can also manage keys programmatically via the REST API.

GET /api/settings/api-keys

Returns the full API registry with obfuscated values and is_set flags.
curl -H "X-Admin-Key: your-admin-key" http://localhost:8000/api/settings/api-keys
Example response:
[
  {
    "id": "ais_api_key",
    "name": "AIS Stream",
    "env_key": "AIS_API_KEY",
    "category": "Maritime",
    "required": true,
    "is_set": true,
    "value_obfuscated": "abcd••••••••"
  }
]

PUT /api/settings/api-keys

Updates a single key. The key takes effect immediately without a restart.
curl -X PUT \
  -H "X-Admin-Key: your-admin-key" \
  -H "Content-Type: application/json" \
  -d '{"env_key": "AIS_API_KEY", "value": "new-key-here"}' \
  http://localhost:8000/api/settings/api-keys
Valid env_key values: AIS_API_KEY, OPENSKY_CLIENT_ID, OPENSKY_CLIENT_SECRET, LTA_ACCOUNT_KEY.

ADMIN_KEY security

ADMIN_KEY protects the following endpoints:
  • GET /api/settings/api-keys
  • PUT /api/settings/api-keys
  • PUT /api/settings/news-feeds
  • POST /api/settings/news-feeds/reset
  • POST /api/system/update
Every request to these endpoints must include the header:
X-Admin-Key: your-admin-key
Requests without a valid key receive 403 Forbidden.
If ADMIN_KEY is not set, all protected endpoints are open to anyone who can reach the backend. The backend logs a CRITICAL warning at startup when this is the case. Always set ADMIN_KEY in production.

Choosing an ADMIN_KEY value

Use a long, random string. You can generate one with:
python3 -c "import secrets; print(secrets.token_urlsafe(32))"
Set it in backend/.env or via Docker secrets (see Environment variables for the _FILE variant).

Build docs developers (and LLMs) love