Python SDK for Notamify public APIs:
- Notamify API v2 (
https://api.notamify.com/api/v2) - Watcher API (
https://watcher.notamify.com)
- Typed API client with one auth token
- Pydantic response/request models
- Pager-style NOTAM listing via
client.notams.*with item iteration andpager.pages - Supported NOTAM endpoints:
GET /notamsGET /notams/rawGET /notams/nearbyGET /notams/archivePOST /notams/briefingGET /notams/briefing/{uuid}POST /notams/prioritisation
- Watcher listener management + webhook logs/secrets
- Listener
modesupport (proddefault,sandboxfor test-only listeners) - Listener lifecycle support via
lifecycle.enabledandlifecycle.types - Sandbox test delivery endpoint (
POST /listeners/{id}/sandbox:send) - Webhook signature verification (
X-Notamify-Signature) - Typed webhook event models for
interpretationandlifecyclepayloads - Embedded receiver + cloudflared helper for local webhook testing
- Strict receiver mode fails fast when webhook secret is missing
pip install notamify-sdkOr with uv:
uv add notamify-sdkFor contributors working from a source checkout:
uv syncEnvironment variables (highest priority):
NOTAMIFY_TOKENNOTAMIFY_API_BASE_URLNOTAMIFY_WATCHER_BASE_URLNOTAMIFY_WEBHOOK_SECRETNOTAMIFY_CONFIG_FILE
Default config file: ~/.config/notamify/config.json
from notamify_sdk import NotamifyClient
client = NotamifyClient(token="YOUR_TOKEN")
# The API accepts at most 30 items per page.
active_notams = list(client.notams.active({
"location": ["KJFK", "KLAX"],
"per_page": 30,
}))
print(len(active_notams))
first_page = next(iter(client.notams.active({
"location": ["KJFK", "KLAX"],
"per_page": 30,
}).pages))
print(first_page.total_count)
job = client.create_async_briefing({
"locations": [{
"location": "KJFK",
"type": "origin",
"starts_at": "2026-02-25T10:00:00Z",
"ends_at": "2026-02-25T12:00:00Z",
}],
})
print(job.uuid)
# Watcher sandbox flow
listener = client.create_listener(
"https://example.trycloudflare.com/webhooks/notamify",
mode="sandbox",
lifecycle={"enabled": False},
)
print(listener.webhook_secret)
sandbox_result = client.send_sandbox_message(listener.id, "SANDBOX-NOTAM-1")
print(sandbox_result.notam_id)The SDK exposes two NOTAM access styles:
client.get_active_notams(...),client.get_raw_notams(...),client.get_nearby_notams(...), andclient.get_historical_notams(...)return a singleNotamListResultpage.client.notams.active(...),client.notams.raw(...),client.notams.nearby(...), andclient.notams.historical(...)return a pager that fetches all pages lazily as you iterate.
Use the pager when you want all NOTAMs across pages:
pager = client.notams.active(
{"location": ["KJFK", "KLAX"]},
per_page=30,
)
for notam in pager:
print(notam.id)If you want everything in memory at once, materialize the pager with list(...):
all_notams = list(
client.notams.active(
{"location": ["KJFK", "KLAX"]},
per_page=30,
)
)If you need page metadata such as page, per_page, or total_count, iterate over pager.pages:
pager = client.notams.active(
{"location": ["KJFK", "KLAX"]},
per_page=30,
)
for page in pager.pages:
print(page.page, page.total_count, len(page.notams))The API allows at most 30 items per page. The SDK validates this with Pydantic and rejects larger per_page values.
The example scripts live in the repository and source distribution under examples/.
They are intended to be run from a source checkout or source distribution, not from an installed wheel alone.
- Production: implement the webhook endpoint in your own application code.
- Verify
X-Notamify-SignatureusingNOTAMIFY_WEBHOOK_SECRET. - Production watcher deliveries include
kind,event_id, andnotam. - Lifecycle watcher deliveries also include
change.changed_notam_idfor the original NOTAM that was cancelled or replaced. - Local development: expose your local app endpoint with
cloudflared, then set watcherwebhook_urlto that tunnel URL. - Sandbox test sends use the same webhook payload DTO as production sends, with mock NOTAM content.
Prerequisite: cloudflared must be installed and available in PATH.
export NOTAMIFY_TOKEN="your_notamify_token"
export LOCAL_APP_URL="http://127.0.0.1:8080/webhooks/notamify"
uv run python ./examples/local_service_run.pyexamples/service_receiver.py: minimal production-style webhook receiverexamples/local_service_run.py: cloudflared tunnel + sandbox delivery flowexamples/notams_fetch.py: straightforward NOTAM query examplesexamples/README.md: setup notes and sample payloads
uv run python -m unittest discover -s tests -p 'test_*.py'MIT