Quickstart

The DYNAM Data API is a managed third-party API. The docs are public; credentials and OAuth client approval are issued by the EasyVFR team after review.

1. Pick auth and licensing model

ModelLicensing basisBest forDeveloper provides
API token + IP allowlistSeat/account basedBackend processing, caching, server-side enrichmentServer IPs, backend use case, expected countries/traffic
End-user OAuthEnd user’s personal DYNAM rightsBrowser/native apps where each user signs inRedirect URIs, OAuth client type, client-direct use case
Application tokenSeat/account based app identityApproved managed integrations or non-OAuth app identityApp name, environments, rotation plan

Important terms:

  • dynam is the public third-party DYNAM OAuth/API scope.
  • static is internal-only for NOTAMbriefing.com and is not issued to third parties.
  • End-user OAuth means your app is approved to request DYNAM tokens, but each signed-in user still needs personal DYNAM rights.
  • Application tokens are separate approved app identities. They are not a substitute for End-user OAuth personal licensing in public browser/native apps.

2. Request access

Submit your integration through the access request page for this environment. Tell us whether you need server processing, End-user OAuth, Application token access, or a combination.

For server access, include server IPs. For End-user OAuth, include redirect URIs and whether the app will call the DYNAM API directly from a browser/native client.

3. Fetch DYNAM GeoJSON

Server-to-server:

curl \
  -H "Authorization: Bearer $DYNAM_API_TOKEN" \
  -H "Accept: application/json" \
  "https://dynam.easyvfr.stream/api/v1/data/airspaces?countries=NL,BE,DE&scope=dynam"

End-user OAuth from an approved client:

const response = await fetch(
  "https://dynam.easyvfr.stream/api/v1/data/airspaces?countries=NL,BE,DE&scope=dynam",
  {
    headers: {
      Authorization: `Bearer ${easyVfrAccessToken}`,
      Accept: "application/json",
    },
  },
);

if (!response.ok) {
  throw new Error(`DYNAM request failed: ${response.status}`);
}

const geojson = await response.json();

Backend cache example:

import requests

url = "https://dynam.easyvfr.stream/api/v1/data/airspaces"
params = {"countries": "NL,BE,DE", "scope": "dynam"}
headers = {"Authorization": f"Bearer {DYNAM_API_TOKEN}", "Accept": "application/json"}

response = requests.get(url, params=params, headers=headers, timeout=60)
response.raise_for_status()
geojson = response.json()

4. Render it

The response is a GeoJSON FeatureCollection. Graphical NOTAMs are features where properties.type === 99 or properties.featureCategory === "graphicalNotam".

See MapLibre/Mapbox for a copy-paste rendering example and Data for the field shape.

Operational notes

  • Fetch after 06:15 UTC for the best day-start picture.
  • Cache large responses on your server when possible.
  • Use X-Data-Version and cache headers to detect published data changes.
  • Treat activation status as operational current-day data, not static reference.

Next

  • Auth - approval, scopes, and license model detail.
  • MapLibre/Mapbox - render airspaces and graphical NOTAMs.
  • Data - response shape and map fields.
  • Reference - OpenAPI.