> For the complete documentation index, see [llms.txt](https://skymerse.gitbook.io/notamify-api/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://skymerse.gitbook.io/notamify-api/notam-watcher/notam-watcher-api.md).

# NOTAM Watcher API

The **Notamify Watcher Service** allows automatic retrieval of new interpretations in Notamify based on configurable filters.\
The service supports listener management via webhooks, enabling applications to subscribe to NOTAM updates by airport code, category, subcategory, or specific NOTAM identifiers.

The Watcher service charges credits based on the number of NOTAM deliveries sent to registered listeners:

* **1 credit = 15 shipments**
* Each shipment increments a counter for the user.
* When the counter reaches 15, the service deducts 1 credit and resets the counter. [Lifecycle ](/notamify-api/notam-watcher/watcher-api-webhook-messages.md#lifecycle-message-example)messages are not chargeable.
* If the user has no credits remaining, further shipments are blocked until credits are topped up.

An account can have up to 15 listeners.

If you specified `webhook_url` the service will provide each new notam for the filter as described in [Watcher API Webhook messages](/notamify-api/notam-watcher/watcher-api-webhook-messages.md).

Watcher API expects to receive a `2xx` success response, such as `200`, after delivering a webhook message. 25 consecutive failed deliveries will pause the listener by setting `active: false`.

#### Python SDK Example

The [Notamify Python SDK](https://github.com/skymerse/notamify-sdk-python) provides typed methods for all Watcher operations:

```python
from notamify_sdk import NotamifyClient

client = NotamifyClient(token="YOUR_API_KEY")

# List all listeners
listeners = client.list_listeners()
for listener in listeners:
    print(f"{listener.name} ({listener.id}) — active: {listener.active}")

# Create a listener with filters
listener = client.create_listener(
    name="JFK Runway Monitor",
    webhook_url="https://your-server.com/webhooks/notamify",
    filters={
        "notam_icao": ["KJFK"],
        "category": ["RUNWAY"],
    },
    lifecycle_enabled=True,
    mode="prod",
)
print(f"Created listener: {listener.id}")

# Update a listener
updated = client.update_listener(
    listener.id,
    filters={
        "notam_icao": ["KJFK", "KEWR"],
        "category": ["AERODROME", "OBSTACLES"],
    },
)

# Delete a listener
client.delete_listener(listener.id)

# Sandbox testing — trigger a test delivery
result = client.send_sandbox_message(listener.id)
print(f"Sandbox delivery: {result}")
```

Use [Notamify API](/notamify-api/basics/authentication-guide.md) key to validate the requests. Received webhook messages should be authenticated via Webhook Secret. Read more: [Webhook Security](/notamify-api/notam-watcher/webhook-security.md)

## List listeners

> Returns all registered listeners for the authenticated account.

```json
{"openapi":"3.1.0","info":{"title":"Notamify Watcher API","version":"1.0.0"},"servers":[{"url":"https://watcher.notamify.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"ListenersResponse":{"type":"object","properties":{"listeners":{"type":"array","items":{"$ref":"#/components/schemas/Listener"}}},"required":["listeners"]},"Listener":{"type":"object","properties":{"id":{"type":"string"},"team_id":{"type":"string","description":"Team context captured when the listener was created or updated by a team-authenticated principal. Team-level alert email profiles apply only when this value is present."},"name":{"type":"string","maxLength":100,"description":"Optional human-readable name for the listener (max 100 characters)."},"webhook_url":{"type":"string","format":"uri","description":"Destination HTTPS/HTTP endpoint for notifications. Must be a public URL, not localhost or 192.168.x.x/0.0.x.x range. Each owner can have at most one active trycloudflare.com quick tunnel webhook listener."},"emails":{"type":"array","maxItems":3,"items":{"type":"string","format":"email"},"description":"Optional email recipients for Postmark delivery."},"filters":{"$ref":"#/components/schemas/Filters"},"lifecycle":{"$ref":"#/components/schemas/Lifecycle"},"metadata":{"$ref":"#/components/schemas/ListenerMetadata"},"active":{"type":"boolean","description":"Whether the listener is active and will receive notifications. Inactive listeners are skipped during dispatch."},"mode":{"$ref":"#/components/schemas/ListenerMode"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"required":["id","filters","lifecycle","metadata","active","mode","created_at","updated_at"]},"Filters":{"type":"object","description":"Supported interpretation filter fields. Values are case-insensitive; duplicates are ignored. Within a field, any value may match (OR). Across fields, all fields must match (AND), except the aircraft applicability convenience fields are merged into affected_element scope alternatives. For category, the special value 'all' matches any category. notam_type applies only to normal interpreted deliveries and supports only NOTAMN/NOTAMR (N/R). aircraft_type accepts only semantic values FIXED_WING, HELICOPTER, and GLIDER. aircraft_designator accepts only variant designators from the notamify-data aircraft catalog. aircraft_family accepts only family IDs from that catalog and expands to catalog variant designators before matching semantics.aircraft_designator. For affected_element, provide an object describing an effect, a type, a subtype, an identifier, applies_to operational scope, and/or semantic changes. Identifier matching is case-insensitive and uses '*' as a multi-character wildcard. applies_to values are strings or arrays of strings keyed by semantic dimension; NOTAM exceptions subtract from that scope and can prevent a match. changes entries are ORed within one affected_element filter and must match a semantics.changes[] entry on the same affected element. Relative time_windows evaluate against NOTAM schedule windows in UTC; absolute time_windows evaluate RFC3339 datetime windows.","properties":{"notam_icao":{"type":"array","items":{"type":"string"},"description":"ICAO airport codes to match (e.g., EPWA, EGLL)."},"notam_type":{"type":"array","items":{"type":"string","enum":["N","R"]},"description":"NOTAM type to match for normal interpreted deliveries only. Allowed values: N (NOTAMN), R (NOTAMR). Selecting R means the delivered notam itself is a replacement NOTAM. It does not mean the payload will contain the previous NOTAM that was updated. Lifecycle cancellation/replacement notifications are controlled separately by the lifecycle object, where change.changed_notam_id identifies the previous NOTAM. NOTAMC (C) is not a valid filter value."},"airport_type":{"type":"array","items":{"type":"string","enum":["small_airport","medium_airport","large_airport"]},"description":"Airport size to match when ICAO codes are omitted."},"aircraft_type":{"type":"array","items":{"type":"string","enum":["FIXED_WING","HELICOPTER","GLIDER"]},"description":"Semantic aircraft family filter. Allowed values are FIXED_WING, HELICOPTER, and GLIDER. Matches affected-element semantics.aircraft_type."},"aircraft_designator":{"type":"array","items":{"type":"string"},"description":"Aircraft catalog variant designator filter. Values must be present in the notamify-data aircraft catalog variants list. Matches affected-element semantics.aircraft_designator."},"aircraft_family":{"type":"array","items":{"type":"string"},"description":"Aircraft catalog family filter. Values must be present in the notamify-data aircraft catalog families list. Families expand to their catalog variant designators and match affected-element semantics.aircraft_designator."},"category":{"type":"array","items":{"type":"string","enum":["all","AERODROME","AIRSPACE","NAVIGATION","COMMUNICATION","OPERATIONS","OBSTACLES","ADMINISTRATIVE","WEATHER","SAFETY","OTHER"]},"description":"Top-level NOTAM categories. Use 'all' to match any category."},"subcategory":{"type":"array","items":{"type":"string","enum":["RUNWAY_OPERATIONS","TAXIWAY_OPERATIONS","APRON_OPERATIONS","AIRPORT_MAINTENANCE","LIGHTING_SYSTEMS","FIRE_AND_RESCUE_SERVICES","OTHER","AIRSPACE_RESTRICTIONS","AIRSPACE_CHANGES","FLOW_CONTROL","MILITARY_ACTIVITY","SPECIAL_USE_AIRSPACE","TEMPORARY_FLIGHT_RESTRICTIONS","NAVIGATION_AID_STATUS","INSTRUMENT_LANDING_SYSTEMS","APPROACH_PROCEDURES","DEPARTURE_PROCEDURES","ROUTE_CHANGES","CHARTS","RADIO_FREQUENCY_CHANGES","COMMUNICATION_EQUIPMENT_STATUS","ATS_COMMUNICATION","RADAR_SERVICES","SURVEILLANCE_SYSTEMS","FLIGHT_PROCEDURES","OPERATING_RESTRICTIONS","SEARCH_AND_RESCUE","EMERGENCY_SERVICES","UAS_DRONE_OPERATIONS","SPECIAL_OPERATIONS","CRANE_OPERATIONS","OBSTACLE_LIGHTING","CONSTRUCTION_ACTIVITY","TEMPORARY_OBSTACLES","NOTAM_MANAGEMENT","PUBLICATION_UPDATES","OFFICE_HOURS","CONTACT_INFORMATION","CHECKLISTS","WEATHER_SERVICES","WEATHER_WARNINGS","SNOWTAM","METEOROLOGICAL_EQUIPMENT","SECURITY_MEASURES","SAFETY_ADVISORIES","WILDLIFE_HAZARDS","BIRD_ACTIVITY"]},"description":"Filter on NOTAM subcategory."},"qcode":{"type":"array","items":{"type":"string","pattern":"^Q(?:[A-Z]{4}|[A-Z]{2}\\*\\*|\\*\\*[A-Z]{2})$"},"description":"Q-code filters to match. Use a full ICAO Q-code such as QMRLC for an exact match, QWW** to match the subject portion, or Q**LC to match the condition portion. Other wildcard placements are rejected."},"time_windows":{"type":"array","maxItems":15,"items":{"type":"object","properties":{"type":{"type":"string","enum":["relative","absolute"],"description":"Window type. Defaults to relative when omitted. Use absolute with start_at/end_at."},"days":{"type":"array","items":{"type":"string","enum":["MO","TU","WE","TH","FR","SA","SU"]},"description":"Relative windows only: optional day-of-week list (UTC). If omitted, any day matches."},"start":{"type":"string","pattern":"^([01]?[0-9]|2[0-3]):[0-5][0-9]$","description":"Relative windows only: start time (UTC) in 24h format."},"end":{"type":"string","pattern":"^(?:([01]?[0-9]|2[0-3]):[0-5][0-9]|24:00)$","description":"Relative windows only: end time (UTC) in 24h format. May be earlier than start to indicate overnight."},"start_at":{"type":"string","format":"date-time","description":"Absolute windows only: inclusive lower bound in RFC3339 format."},"end_at":{"type":"string","format":"date-time","description":"Absolute windows only: exclusive upper bound in RFC3339 format."}},"additionalProperties":false},"description":"Time filters. Relative windows combine days and/or a UTC time range against the NOTAM schedule. Absolute windows use start_at/end_at RFC3339 datetimes."},"affected_element":{"type":"array","description":"List of affected element filters. Each item must provide an effect, a type, a subtype, an identifier, applies_to, changes, or any combination of those fields. Interpretations match if ANY of the specified affected element filters match. Within one affected element filter, all provided fields must match the same affected element. changes entries are ORed and each entry matches one semantics.changes[] item on that affected element. applies_to describes the operation the listener cares about; NOTAM conditions narrow matching and NOTAM exceptions subtract from the requested scope. Identifier matching is case-insensitive and uses '*' as a multi-character wildcard.","items":{"type":"object","properties":{"effect":{"$ref":"#/components/schemas/AffectedElementEffect","description":"Desired effect."},"type":{"$ref":"#/components/schemas/AffectedElementType","description":"Desired element type."},"subtype":{"$ref":"#/components/schemas/AffectedElementSubtype"},"identifier":{"type":"string","description":"Optional affected element identifier. Matching is case-insensitive. Use '*' as a multi-character wildcard, for example '*ILS*' or '*FUEL*'."},"applies_to":{"type":"object","description":"Optional operational scope for this listener. Keys are semantic dimensions such as aircraft_type, aircraft_designator, traffic_type, operational_use, and operation_phase. Values are a string or an array of strings. A NOTAM exception that overlaps this scope prevents a match.","additionalProperties":{"oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}},"changes":{"type":"array","description":"Optional semantic change predicates. Entries are ORed within this affected-element filter. subject input is case-insensitive and stored as the canonical enum value.","items":{"$ref":"#/components/schemas/AffectedElementChangeFilter"},"minItems":1}},"additionalProperties":false}}},"additionalProperties":false},"AffectedElementEffect":{"type":"string","enum":["CLOSED","RESTRICTED","HAZARD","UNSERVICEABLE","WORK_IN_PROGRESS","CAUTION"],"description":"Affected element effects synced from the interpretation schema."},"AffectedElementType":{"type":"string","enum":["AERODROME","RUNWAY","TAXIWAY","APPROACH","NAVAID","AIRSPACE","ROUTE","APRON","LIGHTING","SERVICE","PROCEDURE","OTHER"],"description":"Affected element types synced from the interpretation schema."},"AffectedElementSubtype":{"type":"string","enum":["FUEL","DEICING","ATIS","RADAR_SERVICE","DATALINK_CLEARANCE","FIRE_FIGHTING","GROUND_POWER","AIR_START","PRE_CONDITIONED_AIR","WATER_SERVICE","LAVATORY_SERVICE","OXYGEN_SERVICE","HANDLING","JET_BRIDGE","WEATHER_REPORTING","LOW_VISIBILITY_PROCEDURE","RVR_SERVICE","COMMUNICATION","APPROACH_LIGHTING","PAPI","VASI","STOP_BAR","RUNWAY_EDGE_LIGHT","RUNWAY_CENTERLINE_LIGHT","TAXIWAY_EDGE_LIGHT","TAXIWAY_CENTERLINE_LIGHT","RUNWAY_GUARD_LIGHT","ILS","LOCALIZER","GLIDEPATH","DME","VOR","DVOR","NDB","IAP","ILS_APPROACH","LOC_APPROACH","RNAV_APPROACH","VOR_APPROACH","VISUAL_APPROACH_RULE","CAT_CAPABILITY","MINIMA","SID","STAR","ODP","NOISE_ABATEMENT","MINIMA_AMENDMENT","RESTRICTED_AREA","DANGER_AREA","PROHIBITED_AREA","RESERVED_AREA","TEMP_RESERVED_AREA","SEGREGATED_AREA","TEMPORARY_SEGREGATED_AREA","UAS_AREA","RPAS_AREA","FIR","ATS_ROUTE","ATS_ROUTE_SEGMENT","MANDATORY_ROUTING","CONTINGENCY_ROUTE","TACTICAL_ROUTE","GUIDANCE_SIGN","DIRECTION_SIGN","LOCATION_SIGN","HOLDING_POSITION_SIGN","HOLDING_POSITION_MARKING","DISTANCE_REMAINING_SIGN","SURFACE_MARKING","RUNWAY_CONTAMINATION"],"description":"Known affected element subtypes currently emitted by structured interpretations."},"AffectedElementChangeFilter":{"type":"object","description":"One semantic change predicate. subject is case-insensitive on input and canonicalized to the schema enum value. from and to predicates compare against numeric components in matching semantics.changes operands.","properties":{"subject":{"$ref":"#/components/schemas/AffectedElementChangeSubject"},"from":{"$ref":"#/components/schemas/AffectedElementChangeValuePredicate"},"to":{"$ref":"#/components/schemas/AffectedElementChangeValuePredicate"}},"additionalProperties":false},"AffectedElementChangeSubject":{"type":"string","enum":["FIRE_CATEGORY","HOURS_OF_SERVICE","THRESHOLD_DISPLACEMENT","THRESHOLD_FURTHER_DISPLACEMENT","RUNWAY_LENGTH","TORA","TODA","ASDA","PROCEDURE_CAPABILITY","OCA_OCH","MDA","DA_DH","RVR","VISIBILITY","LDA","SPEED_LIMIT","ALTITUDE_LIMIT","CONTROL_SOURCE","MEHT"],"description":"Affected element semantic change subjects synced from the interpretation schema."},"AffectedElementChangeValuePredicate":{"type":"object","description":"Numeric predicate for listener semantic change filtering. Use value with EQ/NE/LT/LTE/GT/GTE. Use min and max with BETWEEN. unit is optional; when present, the NOTAM operand component must use the same unit.","properties":{"operator":{"$ref":"#/components/schemas/AffectedElementChangeComparisonOperator"},"value":{"type":"number"},"min":{"type":"number"},"max":{"type":"number"},"unit":{"type":"string","description":"Optional unit token such as M or FT. No unit conversion is performed."}},"required":["operator"],"additionalProperties":false},"AffectedElementChangeComparisonOperator":{"type":"string","enum":["EQ","NE","LT","LTE","GT","GTE","BETWEEN"],"description":"Operators supported by listener affected_element changes from/to numeric predicates."},"Lifecycle":{"type":"object","properties":{"enabled":{"type":"boolean","description":"When true, the listener may receive additional lifecycle notifications for NOTAMs that were previously delivered successfully by production webhook and/or email and are later cancelled (NOTAMC) or replaced (NOTAMR). Lifecycle routing is based on prior delivery tracking, not on re-running the normal interpretation filters, except that lifecycle.types can narrow which lifecycle events are delivered. In lifecycle payloads, notam is the NOTAMC/NOTAMR itself and change.changed_notam_id identifies the previously delivered NOTAM that changed. Lifecycle deliveries do not increment shipment credits."},"types":{"type":"array","items":{"type":"string","enum":["CANCELLED","REPLACED"]},"description":"Optional lifecycle event types to receive once lifecycle.enabled is true. If omitted, both CANCELLED and REPLACED lifecycle notifications are eligible."}},"required":["enabled"]},"ListenerMetadata":{"type":"object","properties":{"notams_shipped":{"type":"integer","minimum":0,"description":"Cumulative number of successful production deliveries sent by this listener."},"consecutive_delivery_failures":{"type":"integer","minimum":0,"description":"Current streak of consecutive failed webhook delivery attempts. A successful webhook delivery resets this value to zero. Email delivery attempts do not affect it."},"auto_paused_at":{"type":"string","format":"date-time","description":"Timestamp when the listener was automatically deactivated after exceeding the configured consecutive webhook delivery failure limit."}},"required":["notams_shipped","consecutive_delivery_failures"]},"ListenerMode":{"type":"string","enum":["prod","sandbox"],"description":"Listener delivery mode. 'prod' receives real watcher events. 'sandbox' is for manual test sends only."},"Error":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}},"paths":{"/listeners":{"get":{"summary":"List listeners","description":"Returns all registered listeners for the authenticated account.","responses":{"200":{"description":"List of listeners","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListenersResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal Server Error"}}}}}}
```

## Create listener

> Registers a webhook URL and filters. Filters use OR semantics within a field and AND semantics across fields. For example, category=\['AERODROME','AIRSPACE'] means either category matches; combining with notam\_icao=\['EPWA'] requires both field conditions to match. Using category=\['all'] matches any category. mode defaults to 'prod'. lifecycle.enabled controls separate lifecycle notifications for previously delivered NOTAMs that are later cancelled or replaced; it does not change how normal interpretation filters are evaluated. lifecycle.types can narrow lifecycle notifications to cancelled and/or replaced events. Each owner can have at most one active listener whose webhook host is trycloudflare.com or a subdomain of it.

```json
{"openapi":"3.1.0","info":{"title":"Notamify Watcher API","version":"1.0.0"},"servers":[{"url":"https://watcher.notamify.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"ListenerRequest":{"type":"object","properties":{"name":{"type":"string","maxLength":100,"description":"Optional human-readable name for the listener (max 100 characters)."},"webhook_url":{"type":"string","format":"uri","description":"Destination HTTPS/HTTP endpoint for notifications. Must be a public URL, not localhost or 192.168.x.x/0.0.x.x range. Each owner can have at most one active trycloudflare.com quick tunnel webhook listener. Required when emails are omitted or empty."},"emails":{"type":"array","maxItems":3,"items":{"type":"string","format":"email"},"description":"Optional email recipients for Postmark delivery. Required when webhook_url is omitted."},"filters":{"$ref":"#/components/schemas/Filters"},"lifecycle":{"$ref":"#/components/schemas/LifecycleRequest"},"active":{"type":"boolean","default":true,"description":"Whether the listener is active. Defaults to true if not provided. Set to false to temporarily disable notifications without deleting the listener."},"mode":{"$ref":"#/components/schemas/ListenerMode","default":"prod"}},"required":["filters"]},"Filters":{"type":"object","description":"Supported interpretation filter fields. Values are case-insensitive; duplicates are ignored. Within a field, any value may match (OR). Across fields, all fields must match (AND), except the aircraft applicability convenience fields are merged into affected_element scope alternatives. For category, the special value 'all' matches any category. notam_type applies only to normal interpreted deliveries and supports only NOTAMN/NOTAMR (N/R). aircraft_type accepts only semantic values FIXED_WING, HELICOPTER, and GLIDER. aircraft_designator accepts only variant designators from the notamify-data aircraft catalog. aircraft_family accepts only family IDs from that catalog and expands to catalog variant designators before matching semantics.aircraft_designator. For affected_element, provide an object describing an effect, a type, a subtype, an identifier, applies_to operational scope, and/or semantic changes. Identifier matching is case-insensitive and uses '*' as a multi-character wildcard. applies_to values are strings or arrays of strings keyed by semantic dimension; NOTAM exceptions subtract from that scope and can prevent a match. changes entries are ORed within one affected_element filter and must match a semantics.changes[] entry on the same affected element. Relative time_windows evaluate against NOTAM schedule windows in UTC; absolute time_windows evaluate RFC3339 datetime windows.","properties":{"notam_icao":{"type":"array","items":{"type":"string"},"description":"ICAO airport codes to match (e.g., EPWA, EGLL)."},"notam_type":{"type":"array","items":{"type":"string","enum":["N","R"]},"description":"NOTAM type to match for normal interpreted deliveries only. Allowed values: N (NOTAMN), R (NOTAMR). Selecting R means the delivered notam itself is a replacement NOTAM. It does not mean the payload will contain the previous NOTAM that was updated. Lifecycle cancellation/replacement notifications are controlled separately by the lifecycle object, where change.changed_notam_id identifies the previous NOTAM. NOTAMC (C) is not a valid filter value."},"airport_type":{"type":"array","items":{"type":"string","enum":["small_airport","medium_airport","large_airport"]},"description":"Airport size to match when ICAO codes are omitted."},"aircraft_type":{"type":"array","items":{"type":"string","enum":["FIXED_WING","HELICOPTER","GLIDER"]},"description":"Semantic aircraft family filter. Allowed values are FIXED_WING, HELICOPTER, and GLIDER. Matches affected-element semantics.aircraft_type."},"aircraft_designator":{"type":"array","items":{"type":"string"},"description":"Aircraft catalog variant designator filter. Values must be present in the notamify-data aircraft catalog variants list. Matches affected-element semantics.aircraft_designator."},"aircraft_family":{"type":"array","items":{"type":"string"},"description":"Aircraft catalog family filter. Values must be present in the notamify-data aircraft catalog families list. Families expand to their catalog variant designators and match affected-element semantics.aircraft_designator."},"category":{"type":"array","items":{"type":"string","enum":["all","AERODROME","AIRSPACE","NAVIGATION","COMMUNICATION","OPERATIONS","OBSTACLES","ADMINISTRATIVE","WEATHER","SAFETY","OTHER"]},"description":"Top-level NOTAM categories. Use 'all' to match any category."},"subcategory":{"type":"array","items":{"type":"string","enum":["RUNWAY_OPERATIONS","TAXIWAY_OPERATIONS","APRON_OPERATIONS","AIRPORT_MAINTENANCE","LIGHTING_SYSTEMS","FIRE_AND_RESCUE_SERVICES","OTHER","AIRSPACE_RESTRICTIONS","AIRSPACE_CHANGES","FLOW_CONTROL","MILITARY_ACTIVITY","SPECIAL_USE_AIRSPACE","TEMPORARY_FLIGHT_RESTRICTIONS","NAVIGATION_AID_STATUS","INSTRUMENT_LANDING_SYSTEMS","APPROACH_PROCEDURES","DEPARTURE_PROCEDURES","ROUTE_CHANGES","CHARTS","RADIO_FREQUENCY_CHANGES","COMMUNICATION_EQUIPMENT_STATUS","ATS_COMMUNICATION","RADAR_SERVICES","SURVEILLANCE_SYSTEMS","FLIGHT_PROCEDURES","OPERATING_RESTRICTIONS","SEARCH_AND_RESCUE","EMERGENCY_SERVICES","UAS_DRONE_OPERATIONS","SPECIAL_OPERATIONS","CRANE_OPERATIONS","OBSTACLE_LIGHTING","CONSTRUCTION_ACTIVITY","TEMPORARY_OBSTACLES","NOTAM_MANAGEMENT","PUBLICATION_UPDATES","OFFICE_HOURS","CONTACT_INFORMATION","CHECKLISTS","WEATHER_SERVICES","WEATHER_WARNINGS","SNOWTAM","METEOROLOGICAL_EQUIPMENT","SECURITY_MEASURES","SAFETY_ADVISORIES","WILDLIFE_HAZARDS","BIRD_ACTIVITY"]},"description":"Filter on NOTAM subcategory."},"qcode":{"type":"array","items":{"type":"string","pattern":"^Q(?:[A-Z]{4}|[A-Z]{2}\\*\\*|\\*\\*[A-Z]{2})$"},"description":"Q-code filters to match. Use a full ICAO Q-code such as QMRLC for an exact match, QWW** to match the subject portion, or Q**LC to match the condition portion. Other wildcard placements are rejected."},"time_windows":{"type":"array","maxItems":15,"items":{"type":"object","properties":{"type":{"type":"string","enum":["relative","absolute"],"description":"Window type. Defaults to relative when omitted. Use absolute with start_at/end_at."},"days":{"type":"array","items":{"type":"string","enum":["MO","TU","WE","TH","FR","SA","SU"]},"description":"Relative windows only: optional day-of-week list (UTC). If omitted, any day matches."},"start":{"type":"string","pattern":"^([01]?[0-9]|2[0-3]):[0-5][0-9]$","description":"Relative windows only: start time (UTC) in 24h format."},"end":{"type":"string","pattern":"^(?:([01]?[0-9]|2[0-3]):[0-5][0-9]|24:00)$","description":"Relative windows only: end time (UTC) in 24h format. May be earlier than start to indicate overnight."},"start_at":{"type":"string","format":"date-time","description":"Absolute windows only: inclusive lower bound in RFC3339 format."},"end_at":{"type":"string","format":"date-time","description":"Absolute windows only: exclusive upper bound in RFC3339 format."}},"additionalProperties":false},"description":"Time filters. Relative windows combine days and/or a UTC time range against the NOTAM schedule. Absolute windows use start_at/end_at RFC3339 datetimes."},"affected_element":{"type":"array","description":"List of affected element filters. Each item must provide an effect, a type, a subtype, an identifier, applies_to, changes, or any combination of those fields. Interpretations match if ANY of the specified affected element filters match. Within one affected element filter, all provided fields must match the same affected element. changes entries are ORed and each entry matches one semantics.changes[] item on that affected element. applies_to describes the operation the listener cares about; NOTAM conditions narrow matching and NOTAM exceptions subtract from the requested scope. Identifier matching is case-insensitive and uses '*' as a multi-character wildcard.","items":{"type":"object","properties":{"effect":{"$ref":"#/components/schemas/AffectedElementEffect","description":"Desired effect."},"type":{"$ref":"#/components/schemas/AffectedElementType","description":"Desired element type."},"subtype":{"$ref":"#/components/schemas/AffectedElementSubtype"},"identifier":{"type":"string","description":"Optional affected element identifier. Matching is case-insensitive. Use '*' as a multi-character wildcard, for example '*ILS*' or '*FUEL*'."},"applies_to":{"type":"object","description":"Optional operational scope for this listener. Keys are semantic dimensions such as aircraft_type, aircraft_designator, traffic_type, operational_use, and operation_phase. Values are a string or an array of strings. A NOTAM exception that overlaps this scope prevents a match.","additionalProperties":{"oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}},"changes":{"type":"array","description":"Optional semantic change predicates. Entries are ORed within this affected-element filter. subject input is case-insensitive and stored as the canonical enum value.","items":{"$ref":"#/components/schemas/AffectedElementChangeFilter"},"minItems":1}},"additionalProperties":false}}},"additionalProperties":false},"AffectedElementEffect":{"type":"string","enum":["CLOSED","RESTRICTED","HAZARD","UNSERVICEABLE","WORK_IN_PROGRESS","CAUTION"],"description":"Affected element effects synced from the interpretation schema."},"AffectedElementType":{"type":"string","enum":["AERODROME","RUNWAY","TAXIWAY","APPROACH","NAVAID","AIRSPACE","ROUTE","APRON","LIGHTING","SERVICE","PROCEDURE","OTHER"],"description":"Affected element types synced from the interpretation schema."},"AffectedElementSubtype":{"type":"string","enum":["FUEL","DEICING","ATIS","RADAR_SERVICE","DATALINK_CLEARANCE","FIRE_FIGHTING","GROUND_POWER","AIR_START","PRE_CONDITIONED_AIR","WATER_SERVICE","LAVATORY_SERVICE","OXYGEN_SERVICE","HANDLING","JET_BRIDGE","WEATHER_REPORTING","LOW_VISIBILITY_PROCEDURE","RVR_SERVICE","COMMUNICATION","APPROACH_LIGHTING","PAPI","VASI","STOP_BAR","RUNWAY_EDGE_LIGHT","RUNWAY_CENTERLINE_LIGHT","TAXIWAY_EDGE_LIGHT","TAXIWAY_CENTERLINE_LIGHT","RUNWAY_GUARD_LIGHT","ILS","LOCALIZER","GLIDEPATH","DME","VOR","DVOR","NDB","IAP","ILS_APPROACH","LOC_APPROACH","RNAV_APPROACH","VOR_APPROACH","VISUAL_APPROACH_RULE","CAT_CAPABILITY","MINIMA","SID","STAR","ODP","NOISE_ABATEMENT","MINIMA_AMENDMENT","RESTRICTED_AREA","DANGER_AREA","PROHIBITED_AREA","RESERVED_AREA","TEMP_RESERVED_AREA","SEGREGATED_AREA","TEMPORARY_SEGREGATED_AREA","UAS_AREA","RPAS_AREA","FIR","ATS_ROUTE","ATS_ROUTE_SEGMENT","MANDATORY_ROUTING","CONTINGENCY_ROUTE","TACTICAL_ROUTE","GUIDANCE_SIGN","DIRECTION_SIGN","LOCATION_SIGN","HOLDING_POSITION_SIGN","HOLDING_POSITION_MARKING","DISTANCE_REMAINING_SIGN","SURFACE_MARKING","RUNWAY_CONTAMINATION"],"description":"Known affected element subtypes currently emitted by structured interpretations."},"AffectedElementChangeFilter":{"type":"object","description":"One semantic change predicate. subject is case-insensitive on input and canonicalized to the schema enum value. from and to predicates compare against numeric components in matching semantics.changes operands.","properties":{"subject":{"$ref":"#/components/schemas/AffectedElementChangeSubject"},"from":{"$ref":"#/components/schemas/AffectedElementChangeValuePredicate"},"to":{"$ref":"#/components/schemas/AffectedElementChangeValuePredicate"}},"additionalProperties":false},"AffectedElementChangeSubject":{"type":"string","enum":["FIRE_CATEGORY","HOURS_OF_SERVICE","THRESHOLD_DISPLACEMENT","THRESHOLD_FURTHER_DISPLACEMENT","RUNWAY_LENGTH","TORA","TODA","ASDA","PROCEDURE_CAPABILITY","OCA_OCH","MDA","DA_DH","RVR","VISIBILITY","LDA","SPEED_LIMIT","ALTITUDE_LIMIT","CONTROL_SOURCE","MEHT"],"description":"Affected element semantic change subjects synced from the interpretation schema."},"AffectedElementChangeValuePredicate":{"type":"object","description":"Numeric predicate for listener semantic change filtering. Use value with EQ/NE/LT/LTE/GT/GTE. Use min and max with BETWEEN. unit is optional; when present, the NOTAM operand component must use the same unit.","properties":{"operator":{"$ref":"#/components/schemas/AffectedElementChangeComparisonOperator"},"value":{"type":"number"},"min":{"type":"number"},"max":{"type":"number"},"unit":{"type":"string","description":"Optional unit token such as M or FT. No unit conversion is performed."}},"required":["operator"],"additionalProperties":false},"AffectedElementChangeComparisonOperator":{"type":"string","enum":["EQ","NE","LT","LTE","GT","GTE","BETWEEN"],"description":"Operators supported by listener affected_element changes from/to numeric predicates."},"LifecycleRequest":{"type":"object","properties":{"enabled":{"type":"boolean","default":false,"description":"Enable additional lifecycle notifications for NOTAMs previously delivered successfully by production webhook and/or email when they are later cancelled (C) or replaced (R). This does not change normal interpretation filter matching, except that lifecycle.types can narrow which lifecycle events are delivered. In lifecycle payloads, notam is the NOTAMC/NOTAMR itself and change.changed_notam_id identifies the previously delivered NOTAM that changed. Lifecycle deliveries do not increment shipment credits."},"types":{"type":"array","items":{"type":"string","enum":["CANCELLED","REPLACED"]},"description":"Optional lifecycle event types to receive when lifecycle.enabled is true. If omitted, both CANCELLED and REPLACED lifecycle notifications are eligible."}},"additionalProperties":false},"ListenerMode":{"type":"string","enum":["prod","sandbox"],"description":"Listener delivery mode. 'prod' receives real watcher events. 'sandbox' is for manual test sends only."},"ListenerWithSecret":{"allOf":[{"$ref":"#/components/schemas/Listener"},{"type":"object","properties":{"webhook_secret":{"type":"string","description":"Webhook signing secret (returned once on creation/rotation)."}}}]},"Listener":{"type":"object","properties":{"id":{"type":"string"},"team_id":{"type":"string","description":"Team context captured when the listener was created or updated by a team-authenticated principal. Team-level alert email profiles apply only when this value is present."},"name":{"type":"string","maxLength":100,"description":"Optional human-readable name for the listener (max 100 characters)."},"webhook_url":{"type":"string","format":"uri","description":"Destination HTTPS/HTTP endpoint for notifications. Must be a public URL, not localhost or 192.168.x.x/0.0.x.x range. Each owner can have at most one active trycloudflare.com quick tunnel webhook listener."},"emails":{"type":"array","maxItems":3,"items":{"type":"string","format":"email"},"description":"Optional email recipients for Postmark delivery."},"filters":{"$ref":"#/components/schemas/Filters"},"lifecycle":{"$ref":"#/components/schemas/Lifecycle"},"metadata":{"$ref":"#/components/schemas/ListenerMetadata"},"active":{"type":"boolean","description":"Whether the listener is active and will receive notifications. Inactive listeners are skipped during dispatch."},"mode":{"$ref":"#/components/schemas/ListenerMode"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"required":["id","filters","lifecycle","metadata","active","mode","created_at","updated_at"]},"Lifecycle":{"type":"object","properties":{"enabled":{"type":"boolean","description":"When true, the listener may receive additional lifecycle notifications for NOTAMs that were previously delivered successfully by production webhook and/or email and are later cancelled (NOTAMC) or replaced (NOTAMR). Lifecycle routing is based on prior delivery tracking, not on re-running the normal interpretation filters, except that lifecycle.types can narrow which lifecycle events are delivered. In lifecycle payloads, notam is the NOTAMC/NOTAMR itself and change.changed_notam_id identifies the previously delivered NOTAM that changed. Lifecycle deliveries do not increment shipment credits."},"types":{"type":"array","items":{"type":"string","enum":["CANCELLED","REPLACED"]},"description":"Optional lifecycle event types to receive once lifecycle.enabled is true. If omitted, both CANCELLED and REPLACED lifecycle notifications are eligible."}},"required":["enabled"]},"ListenerMetadata":{"type":"object","properties":{"notams_shipped":{"type":"integer","minimum":0,"description":"Cumulative number of successful production deliveries sent by this listener."},"consecutive_delivery_failures":{"type":"integer","minimum":0,"description":"Current streak of consecutive failed webhook delivery attempts. A successful webhook delivery resets this value to zero. Email delivery attempts do not affect it."},"auto_paused_at":{"type":"string","format":"date-time","description":"Timestamp when the listener was automatically deactivated after exceeding the configured consecutive webhook delivery failure limit."}},"required":["notams_shipped","consecutive_delivery_failures"]},"Error":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}},"paths":{"/listeners":{"post":{"summary":"Create listener","description":"Registers a webhook URL and filters. Filters use OR semantics within a field and AND semantics across fields. For example, category=['AERODROME','AIRSPACE'] means either category matches; combining with notam_icao=['EPWA'] requires both field conditions to match. Using category=['all'] matches any category. mode defaults to 'prod'. lifecycle.enabled controls separate lifecycle notifications for previously delivered NOTAMs that are later cancelled or replaced; it does not change how normal interpretation filters are evaluated. lifecycle.types can narrow lifecycle notifications to cancelled and/or replaced events. Each owner can have at most one active listener whose webhook host is trycloudflare.com or a subdomain of it.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListenerRequest"}}}},"responses":{"201":{"description":"Listener created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListenerWithSecret"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal Server Error"}}}}}}
```

## Update listener

> Updates webhook URL and/or filters using the same semantics as creation. mode can be changed between 'prod' and 'sandbox'. lifecycle.enabled controls separate lifecycle notifications for previously delivered NOTAMs that are later cancelled or replaced; it does not change how normal interpretation filters are evaluated. lifecycle.types can narrow lifecycle notifications to cancelled and/or replaced events.

```json
{"openapi":"3.1.0","info":{"title":"Notamify Watcher API","version":"1.0.0"},"servers":[{"url":"https://watcher.notamify.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"ListenerRequest":{"type":"object","properties":{"name":{"type":"string","maxLength":100,"description":"Optional human-readable name for the listener (max 100 characters)."},"webhook_url":{"type":"string","format":"uri","description":"Destination HTTPS/HTTP endpoint for notifications. Must be a public URL, not localhost or 192.168.x.x/0.0.x.x range. Each owner can have at most one active trycloudflare.com quick tunnel webhook listener. Required when emails are omitted or empty."},"emails":{"type":"array","maxItems":3,"items":{"type":"string","format":"email"},"description":"Optional email recipients for Postmark delivery. Required when webhook_url is omitted."},"filters":{"$ref":"#/components/schemas/Filters"},"lifecycle":{"$ref":"#/components/schemas/LifecycleRequest"},"active":{"type":"boolean","default":true,"description":"Whether the listener is active. Defaults to true if not provided. Set to false to temporarily disable notifications without deleting the listener."},"mode":{"$ref":"#/components/schemas/ListenerMode","default":"prod"}},"required":["filters"]},"Filters":{"type":"object","description":"Supported interpretation filter fields. Values are case-insensitive; duplicates are ignored. Within a field, any value may match (OR). Across fields, all fields must match (AND), except the aircraft applicability convenience fields are merged into affected_element scope alternatives. For category, the special value 'all' matches any category. notam_type applies only to normal interpreted deliveries and supports only NOTAMN/NOTAMR (N/R). aircraft_type accepts only semantic values FIXED_WING, HELICOPTER, and GLIDER. aircraft_designator accepts only variant designators from the notamify-data aircraft catalog. aircraft_family accepts only family IDs from that catalog and expands to catalog variant designators before matching semantics.aircraft_designator. For affected_element, provide an object describing an effect, a type, a subtype, an identifier, applies_to operational scope, and/or semantic changes. Identifier matching is case-insensitive and uses '*' as a multi-character wildcard. applies_to values are strings or arrays of strings keyed by semantic dimension; NOTAM exceptions subtract from that scope and can prevent a match. changes entries are ORed within one affected_element filter and must match a semantics.changes[] entry on the same affected element. Relative time_windows evaluate against NOTAM schedule windows in UTC; absolute time_windows evaluate RFC3339 datetime windows.","properties":{"notam_icao":{"type":"array","items":{"type":"string"},"description":"ICAO airport codes to match (e.g., EPWA, EGLL)."},"notam_type":{"type":"array","items":{"type":"string","enum":["N","R"]},"description":"NOTAM type to match for normal interpreted deliveries only. Allowed values: N (NOTAMN), R (NOTAMR). Selecting R means the delivered notam itself is a replacement NOTAM. It does not mean the payload will contain the previous NOTAM that was updated. Lifecycle cancellation/replacement notifications are controlled separately by the lifecycle object, where change.changed_notam_id identifies the previous NOTAM. NOTAMC (C) is not a valid filter value."},"airport_type":{"type":"array","items":{"type":"string","enum":["small_airport","medium_airport","large_airport"]},"description":"Airport size to match when ICAO codes are omitted."},"aircraft_type":{"type":"array","items":{"type":"string","enum":["FIXED_WING","HELICOPTER","GLIDER"]},"description":"Semantic aircraft family filter. Allowed values are FIXED_WING, HELICOPTER, and GLIDER. Matches affected-element semantics.aircraft_type."},"aircraft_designator":{"type":"array","items":{"type":"string"},"description":"Aircraft catalog variant designator filter. Values must be present in the notamify-data aircraft catalog variants list. Matches affected-element semantics.aircraft_designator."},"aircraft_family":{"type":"array","items":{"type":"string"},"description":"Aircraft catalog family filter. Values must be present in the notamify-data aircraft catalog families list. Families expand to their catalog variant designators and match affected-element semantics.aircraft_designator."},"category":{"type":"array","items":{"type":"string","enum":["all","AERODROME","AIRSPACE","NAVIGATION","COMMUNICATION","OPERATIONS","OBSTACLES","ADMINISTRATIVE","WEATHER","SAFETY","OTHER"]},"description":"Top-level NOTAM categories. Use 'all' to match any category."},"subcategory":{"type":"array","items":{"type":"string","enum":["RUNWAY_OPERATIONS","TAXIWAY_OPERATIONS","APRON_OPERATIONS","AIRPORT_MAINTENANCE","LIGHTING_SYSTEMS","FIRE_AND_RESCUE_SERVICES","OTHER","AIRSPACE_RESTRICTIONS","AIRSPACE_CHANGES","FLOW_CONTROL","MILITARY_ACTIVITY","SPECIAL_USE_AIRSPACE","TEMPORARY_FLIGHT_RESTRICTIONS","NAVIGATION_AID_STATUS","INSTRUMENT_LANDING_SYSTEMS","APPROACH_PROCEDURES","DEPARTURE_PROCEDURES","ROUTE_CHANGES","CHARTS","RADIO_FREQUENCY_CHANGES","COMMUNICATION_EQUIPMENT_STATUS","ATS_COMMUNICATION","RADAR_SERVICES","SURVEILLANCE_SYSTEMS","FLIGHT_PROCEDURES","OPERATING_RESTRICTIONS","SEARCH_AND_RESCUE","EMERGENCY_SERVICES","UAS_DRONE_OPERATIONS","SPECIAL_OPERATIONS","CRANE_OPERATIONS","OBSTACLE_LIGHTING","CONSTRUCTION_ACTIVITY","TEMPORARY_OBSTACLES","NOTAM_MANAGEMENT","PUBLICATION_UPDATES","OFFICE_HOURS","CONTACT_INFORMATION","CHECKLISTS","WEATHER_SERVICES","WEATHER_WARNINGS","SNOWTAM","METEOROLOGICAL_EQUIPMENT","SECURITY_MEASURES","SAFETY_ADVISORIES","WILDLIFE_HAZARDS","BIRD_ACTIVITY"]},"description":"Filter on NOTAM subcategory."},"qcode":{"type":"array","items":{"type":"string","pattern":"^Q(?:[A-Z]{4}|[A-Z]{2}\\*\\*|\\*\\*[A-Z]{2})$"},"description":"Q-code filters to match. Use a full ICAO Q-code such as QMRLC for an exact match, QWW** to match the subject portion, or Q**LC to match the condition portion. Other wildcard placements are rejected."},"time_windows":{"type":"array","maxItems":15,"items":{"type":"object","properties":{"type":{"type":"string","enum":["relative","absolute"],"description":"Window type. Defaults to relative when omitted. Use absolute with start_at/end_at."},"days":{"type":"array","items":{"type":"string","enum":["MO","TU","WE","TH","FR","SA","SU"]},"description":"Relative windows only: optional day-of-week list (UTC). If omitted, any day matches."},"start":{"type":"string","pattern":"^([01]?[0-9]|2[0-3]):[0-5][0-9]$","description":"Relative windows only: start time (UTC) in 24h format."},"end":{"type":"string","pattern":"^(?:([01]?[0-9]|2[0-3]):[0-5][0-9]|24:00)$","description":"Relative windows only: end time (UTC) in 24h format. May be earlier than start to indicate overnight."},"start_at":{"type":"string","format":"date-time","description":"Absolute windows only: inclusive lower bound in RFC3339 format."},"end_at":{"type":"string","format":"date-time","description":"Absolute windows only: exclusive upper bound in RFC3339 format."}},"additionalProperties":false},"description":"Time filters. Relative windows combine days and/or a UTC time range against the NOTAM schedule. Absolute windows use start_at/end_at RFC3339 datetimes."},"affected_element":{"type":"array","description":"List of affected element filters. Each item must provide an effect, a type, a subtype, an identifier, applies_to, changes, or any combination of those fields. Interpretations match if ANY of the specified affected element filters match. Within one affected element filter, all provided fields must match the same affected element. changes entries are ORed and each entry matches one semantics.changes[] item on that affected element. applies_to describes the operation the listener cares about; NOTAM conditions narrow matching and NOTAM exceptions subtract from the requested scope. Identifier matching is case-insensitive and uses '*' as a multi-character wildcard.","items":{"type":"object","properties":{"effect":{"$ref":"#/components/schemas/AffectedElementEffect","description":"Desired effect."},"type":{"$ref":"#/components/schemas/AffectedElementType","description":"Desired element type."},"subtype":{"$ref":"#/components/schemas/AffectedElementSubtype"},"identifier":{"type":"string","description":"Optional affected element identifier. Matching is case-insensitive. Use '*' as a multi-character wildcard, for example '*ILS*' or '*FUEL*'."},"applies_to":{"type":"object","description":"Optional operational scope for this listener. Keys are semantic dimensions such as aircraft_type, aircraft_designator, traffic_type, operational_use, and operation_phase. Values are a string or an array of strings. A NOTAM exception that overlaps this scope prevents a match.","additionalProperties":{"oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}},"changes":{"type":"array","description":"Optional semantic change predicates. Entries are ORed within this affected-element filter. subject input is case-insensitive and stored as the canonical enum value.","items":{"$ref":"#/components/schemas/AffectedElementChangeFilter"},"minItems":1}},"additionalProperties":false}}},"additionalProperties":false},"AffectedElementEffect":{"type":"string","enum":["CLOSED","RESTRICTED","HAZARD","UNSERVICEABLE","WORK_IN_PROGRESS","CAUTION"],"description":"Affected element effects synced from the interpretation schema."},"AffectedElementType":{"type":"string","enum":["AERODROME","RUNWAY","TAXIWAY","APPROACH","NAVAID","AIRSPACE","ROUTE","APRON","LIGHTING","SERVICE","PROCEDURE","OTHER"],"description":"Affected element types synced from the interpretation schema."},"AffectedElementSubtype":{"type":"string","enum":["FUEL","DEICING","ATIS","RADAR_SERVICE","DATALINK_CLEARANCE","FIRE_FIGHTING","GROUND_POWER","AIR_START","PRE_CONDITIONED_AIR","WATER_SERVICE","LAVATORY_SERVICE","OXYGEN_SERVICE","HANDLING","JET_BRIDGE","WEATHER_REPORTING","LOW_VISIBILITY_PROCEDURE","RVR_SERVICE","COMMUNICATION","APPROACH_LIGHTING","PAPI","VASI","STOP_BAR","RUNWAY_EDGE_LIGHT","RUNWAY_CENTERLINE_LIGHT","TAXIWAY_EDGE_LIGHT","TAXIWAY_CENTERLINE_LIGHT","RUNWAY_GUARD_LIGHT","ILS","LOCALIZER","GLIDEPATH","DME","VOR","DVOR","NDB","IAP","ILS_APPROACH","LOC_APPROACH","RNAV_APPROACH","VOR_APPROACH","VISUAL_APPROACH_RULE","CAT_CAPABILITY","MINIMA","SID","STAR","ODP","NOISE_ABATEMENT","MINIMA_AMENDMENT","RESTRICTED_AREA","DANGER_AREA","PROHIBITED_AREA","RESERVED_AREA","TEMP_RESERVED_AREA","SEGREGATED_AREA","TEMPORARY_SEGREGATED_AREA","UAS_AREA","RPAS_AREA","FIR","ATS_ROUTE","ATS_ROUTE_SEGMENT","MANDATORY_ROUTING","CONTINGENCY_ROUTE","TACTICAL_ROUTE","GUIDANCE_SIGN","DIRECTION_SIGN","LOCATION_SIGN","HOLDING_POSITION_SIGN","HOLDING_POSITION_MARKING","DISTANCE_REMAINING_SIGN","SURFACE_MARKING","RUNWAY_CONTAMINATION"],"description":"Known affected element subtypes currently emitted by structured interpretations."},"AffectedElementChangeFilter":{"type":"object","description":"One semantic change predicate. subject is case-insensitive on input and canonicalized to the schema enum value. from and to predicates compare against numeric components in matching semantics.changes operands.","properties":{"subject":{"$ref":"#/components/schemas/AffectedElementChangeSubject"},"from":{"$ref":"#/components/schemas/AffectedElementChangeValuePredicate"},"to":{"$ref":"#/components/schemas/AffectedElementChangeValuePredicate"}},"additionalProperties":false},"AffectedElementChangeSubject":{"type":"string","enum":["FIRE_CATEGORY","HOURS_OF_SERVICE","THRESHOLD_DISPLACEMENT","THRESHOLD_FURTHER_DISPLACEMENT","RUNWAY_LENGTH","TORA","TODA","ASDA","PROCEDURE_CAPABILITY","OCA_OCH","MDA","DA_DH","RVR","VISIBILITY","LDA","SPEED_LIMIT","ALTITUDE_LIMIT","CONTROL_SOURCE","MEHT"],"description":"Affected element semantic change subjects synced from the interpretation schema."},"AffectedElementChangeValuePredicate":{"type":"object","description":"Numeric predicate for listener semantic change filtering. Use value with EQ/NE/LT/LTE/GT/GTE. Use min and max with BETWEEN. unit is optional; when present, the NOTAM operand component must use the same unit.","properties":{"operator":{"$ref":"#/components/schemas/AffectedElementChangeComparisonOperator"},"value":{"type":"number"},"min":{"type":"number"},"max":{"type":"number"},"unit":{"type":"string","description":"Optional unit token such as M or FT. No unit conversion is performed."}},"required":["operator"],"additionalProperties":false},"AffectedElementChangeComparisonOperator":{"type":"string","enum":["EQ","NE","LT","LTE","GT","GTE","BETWEEN"],"description":"Operators supported by listener affected_element changes from/to numeric predicates."},"LifecycleRequest":{"type":"object","properties":{"enabled":{"type":"boolean","default":false,"description":"Enable additional lifecycle notifications for NOTAMs previously delivered successfully by production webhook and/or email when they are later cancelled (C) or replaced (R). This does not change normal interpretation filter matching, except that lifecycle.types can narrow which lifecycle events are delivered. In lifecycle payloads, notam is the NOTAMC/NOTAMR itself and change.changed_notam_id identifies the previously delivered NOTAM that changed. Lifecycle deliveries do not increment shipment credits."},"types":{"type":"array","items":{"type":"string","enum":["CANCELLED","REPLACED"]},"description":"Optional lifecycle event types to receive when lifecycle.enabled is true. If omitted, both CANCELLED and REPLACED lifecycle notifications are eligible."}},"additionalProperties":false},"ListenerMode":{"type":"string","enum":["prod","sandbox"],"description":"Listener delivery mode. 'prod' receives real watcher events. 'sandbox' is for manual test sends only."},"Listener":{"type":"object","properties":{"id":{"type":"string"},"team_id":{"type":"string","description":"Team context captured when the listener was created or updated by a team-authenticated principal. Team-level alert email profiles apply only when this value is present."},"name":{"type":"string","maxLength":100,"description":"Optional human-readable name for the listener (max 100 characters)."},"webhook_url":{"type":"string","format":"uri","description":"Destination HTTPS/HTTP endpoint for notifications. Must be a public URL, not localhost or 192.168.x.x/0.0.x.x range. Each owner can have at most one active trycloudflare.com quick tunnel webhook listener."},"emails":{"type":"array","maxItems":3,"items":{"type":"string","format":"email"},"description":"Optional email recipients for Postmark delivery."},"filters":{"$ref":"#/components/schemas/Filters"},"lifecycle":{"$ref":"#/components/schemas/Lifecycle"},"metadata":{"$ref":"#/components/schemas/ListenerMetadata"},"active":{"type":"boolean","description":"Whether the listener is active and will receive notifications. Inactive listeners are skipped during dispatch."},"mode":{"$ref":"#/components/schemas/ListenerMode"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"required":["id","filters","lifecycle","metadata","active","mode","created_at","updated_at"]},"Lifecycle":{"type":"object","properties":{"enabled":{"type":"boolean","description":"When true, the listener may receive additional lifecycle notifications for NOTAMs that were previously delivered successfully by production webhook and/or email and are later cancelled (NOTAMC) or replaced (NOTAMR). Lifecycle routing is based on prior delivery tracking, not on re-running the normal interpretation filters, except that lifecycle.types can narrow which lifecycle events are delivered. In lifecycle payloads, notam is the NOTAMC/NOTAMR itself and change.changed_notam_id identifies the previously delivered NOTAM that changed. Lifecycle deliveries do not increment shipment credits."},"types":{"type":"array","items":{"type":"string","enum":["CANCELLED","REPLACED"]},"description":"Optional lifecycle event types to receive once lifecycle.enabled is true. If omitted, both CANCELLED and REPLACED lifecycle notifications are eligible."}},"required":["enabled"]},"ListenerMetadata":{"type":"object","properties":{"notams_shipped":{"type":"integer","minimum":0,"description":"Cumulative number of successful production deliveries sent by this listener."},"consecutive_delivery_failures":{"type":"integer","minimum":0,"description":"Current streak of consecutive failed webhook delivery attempts. A successful webhook delivery resets this value to zero. Email delivery attempts do not affect it."},"auto_paused_at":{"type":"string","format":"date-time","description":"Timestamp when the listener was automatically deactivated after exceeding the configured consecutive webhook delivery failure limit."}},"required":["notams_shipped","consecutive_delivery_failures"]},"Error":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}},"paths":{"/listeners/{id}":{"put":{"summary":"Update listener","description":"Updates webhook URL and/or filters using the same semantics as creation. mode can be changed between 'prod' and 'sandbox'. lifecycle.enabled controls separate lifecycle notifications for previously delivered NOTAMs that are later cancelled or replaced; it does not change how normal interpretation filters are evaluated. lifecycle.types can narrow lifecycle notifications to cancelled and/or replaced events.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListenerRequest"}}}},"responses":{"200":{"description":"Listener updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Listener"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal Server Error"}}}}}}
```

## DELETE /listeners/{id}

> Delete listener

```json
{"openapi":"3.1.0","info":{"title":"Notamify Watcher API","version":"1.0.0"},"servers":[{"url":"https://watcher.notamify.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"Error":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}},"paths":{"/listeners/{id}":{"delete":{"summary":"Delete listener","responses":{"204":{"description":"Deleted"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal Server Error"}}}}}}
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://skymerse.gitbook.io/notamify-api/notam-watcher/notam-watcher-api.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
