# 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.

User can have maximally up to 15 active 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).

#### 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}")
```

## 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"},"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."},"email":{"type":"string","format":"email","description":"Optional email recipient for 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). For category, the special value 'all' matches any category. notam_type applies only to normal interpreted deliveries and supports only NOTAMN/NOTAMR (N/R). For affected_element, provide an object describing an effect, a type, a subtype, an identifier, and/or clause filters under conditions and exceptions. The easiest setup is to copy clause objects from interpretation.affected_elements[].semantics. Identifier matching is case-insensitive and uses '*' as a multi-character wildcard. Clause matching is case-insensitive and supports partial clause objects such as dimension-only or dimension+operator filters. Clause filters exclude only explicit same-dimension semantic conflicts; NOTAMs without that semantics dimension still match. 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."},"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","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, clause filters under conditions/exceptions, or any combination of those fields. Interpretations match if ANY of the specified affected element filters match. Within one affected element filter, all provided non-clause fields must match the same affected element. Clause filters exclude explicit same-dimension semantic conflicts but do not require the NOTAM to include that semantics dimension. Identifier matching is case-insensitive and uses '*' as a multi-character wildcard.","items":{"type":"object","properties":{"effect":{"type":"string","enum":["CLOSED","RESTRICTED","HAZARD","UNSERVICEABLE","WORK_IN_PROGRESS","CAUTION"],"description":"Desired effect."},"type":{"type":"string","enum":["AERODROME","RUNWAY","TAXIWAY","APPROACH","NAVAID","AIRSPACE","APRON","LIGHTING","SERVICE","PROCEDURE","OTHER"],"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*'."},"conditions":{"type":"array","description":"Optional semantics condition clauses. The easiest setup is to copy clauses from interpretation.affected_elements[].semantics.conditions. A supplied clause matches when the affected element has no same-dimension condition or has a compatible same-dimension condition; incompatible same-dimension conditions exclude the NOTAM.","items":{"$ref":"#/components/schemas/AffectedElementClauseFilter"}},"exceptions":{"type":"array","description":"Optional semantics exception clauses. The easiest setup is to copy clauses from interpretation.affected_elements[].semantics.exceptions. A supplied clause matches when the affected element has no same-dimension exception or has a compatible same-dimension exception; incompatible same-dimension exceptions exclude the NOTAM.","items":{"$ref":"#/components/schemas/AffectedElementClauseFilter"}}}}}},"additionalProperties":false},"AffectedElementSubtype":{"type":"string","enum":["ILS_CATEGORY"],"description":"Known affected element subtypes currently emitted by structured interpretations."},"AffectedElementClauseFilter":{"type":"object","properties":{"dimension":{"type":"string","description":"Clause dimension. Required when the clause object is present. Use OPERATIONAL_PHASE with OperationPhaseLiteral values such as TAKEOFF or LANDING, and OPERATIONAL_USE with OperationalUseLiteral values such as ALTERNATE or DESTINATION."},"operator":{"type":"string","description":"Optional clause operator."},"value":{"$ref":"#/components/schemas/AffectedElementClauseValue"},"unit":{"type":"string","description":"Optional clause unit."},"details":{"type":"string","description":"Optional clause details."}}},"AffectedElementClauseValue":{"description":"Structured clause value. Known enum-backed semantics tokens and procedure capability values are listed explicitly; other string/number/boolean/array/object payloads remain allowed for forward compatibility.","anyOf":[{"$ref":"#/components/schemas/IntegerMeasurementValue"},{"$ref":"#/components/schemas/FractionalMeasurementValue"},{"$ref":"#/components/schemas/GroupedMeasurementValue"},{"$ref":"#/components/schemas/ProcedureCapability"},{"$ref":"#/components/schemas/OperationPhaseLiteral"},{"$ref":"#/components/schemas/OperationalUseLiteral"},{"type":"array","items":{"$ref":"#/components/schemas/OperationPhaseLiteral"},"minItems":1},{"type":"array","items":{"$ref":"#/components/schemas/OperationalUseLiteral"},"minItems":1},{"$ref":"#/components/schemas/AffectedElementSemanticToken"},{"type":"array","items":{"$ref":"#/components/schemas/AffectedElementSemanticToken"},"minItems":1},{"type":"array","items":{"type":"string"},"minItems":1},{"type":"string"},{"type":"number"},{"type":"integer"},{"type":"boolean"},{"type":"object","additionalProperties":true}]},"IntegerMeasurementValue":{"type":"object","properties":{"kind":{"type":"string","const":"MEASUREMENT","default":"MEASUREMENT"},"raw_string":{"type":"string"},"value":{"type":"integer"},"unit":{"type":"string"}},"required":["raw_string","value","unit"]},"FractionalMeasurementValue":{"type":"object","properties":{"kind":{"type":"string","const":"FRACTIONAL_MEASUREMENT","default":"FRACTIONAL_MEASUREMENT"},"raw_string":{"type":"string"},"numerator":{"type":"integer"},"denominator":{"type":"integer"},"unit":{"type":"string"}},"required":["raw_string","numerator","denominator","unit"]},"GroupedMeasurementValue":{"type":"object","properties":{"kind":{"type":"string","const":"MEASUREMENTS","default":"MEASUREMENTS"},"raw_string":{"type":"string"},"values":{"type":"array","items":{"$ref":"#/components/schemas/MeasurementComponentValue"}}},"required":["raw_string"]},"MeasurementComponentValue":{"type":"object","properties":{"type":{"type":"string","enum":["ALTITUDE","HEIGHT"]},"value":{"type":"integer"},"unit":{"type":"string"}},"required":["type","value","unit"]},"ProcedureCapability":{"type":"object","properties":{"scheme":{"type":"string","const":"ILS_CATEGORY"},"category":{"type":"string","enum":["CAT_I","CAT_II","CAT_IIIA","CAT_IIIB","CAT_IIIC"]},"level":{"type":"string","enum":["LVL_1","LVL_2","LVL_3"]},"classification":{"type":"string"},"source_label":{"type":"string"}},"required":["scheme"]},"OperationPhaseLiteral":{"type":"string","enum":["TAKEOFF","LANDING","APPROACH","ARRIVAL","DEPARTURE"],"description":"Known semantics values for clauses where dimension is OPERATIONAL_PHASE."},"OperationalUseLiteral":{"type":"string","enum":["ALTERNATE","DIVERSION","DESTINATION","DEPARTURE"],"description":"Known semantics values for clauses where dimension is OPERATIONAL_USE."},"AffectedElementSemanticToken":{"type":"string","enum":["TAKEOFF","LANDING","APPROACH","ARRIVAL","DEPARTURE","LOCAL_FLIGHT","TRAINING_FLIGHT","CIRCUIT","INTERNATIONAL_FLIGHT","FIXED_WING","HELICOPTER","GLIDER","GENERAL_AVIATION","NON_SCHEDULED","NON_COMMERCIAL","SCHEDULED","IFR","VFR","STATE","MILITARY","A","B","C","D","E","F","H","LIGHT","MEDIUM","HEAVY","SUPER","ALTERNATE","DIVERSION","DESTINATION","AVGAS_100","AVGAS_100LL","AVGAS_UL91","JET_A","JET_A1","JET_B","JP_4","JP_5","JP_8","TS_1","MOGAS","HYDRANT","BOWSER","TANKER","FOLLOW_ME","MARSHALLER","PPR","EMERGENCY_FLIGHT","MEDICAL_FLIGHT","SAR_FLIGHT","STATE_FLIGHT","CUSTOMS_OFFICIAL_TRAFFIC","ALS","ALSF_2","SDF","ATIS","DATALINK_CLEARANCE","VGSI","PAPI","VASI","GLIDEPATH","GLIDESLOPE","LOCALIZER","RVR_MEASURING_EQUIPMENT","INNER_MARKER","DME","RADIO_ALTIMETER","RNAV_GPS","RADAR","AUTOPILOT","AIRSHOW","MILITARY_ACTIVITY","BLASTING_ACTIVITY","ROCKET_LAUNCH","UAS_ACTIVITY"],"description":"Known structured semantics literal tokens."},"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."}},"required":["notams_shipped"]},"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 email is omitted."},"email":{"type":"string","format":"email","description":"Optional email recipient 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). For category, the special value 'all' matches any category. notam_type applies only to normal interpreted deliveries and supports only NOTAMN/NOTAMR (N/R). For affected_element, provide an object describing an effect, a type, a subtype, an identifier, and/or clause filters under conditions and exceptions. The easiest setup is to copy clause objects from interpretation.affected_elements[].semantics. Identifier matching is case-insensitive and uses '*' as a multi-character wildcard. Clause matching is case-insensitive and supports partial clause objects such as dimension-only or dimension+operator filters. Clause filters exclude only explicit same-dimension semantic conflicts; NOTAMs without that semantics dimension still match. 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."},"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","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, clause filters under conditions/exceptions, or any combination of those fields. Interpretations match if ANY of the specified affected element filters match. Within one affected element filter, all provided non-clause fields must match the same affected element. Clause filters exclude explicit same-dimension semantic conflicts but do not require the NOTAM to include that semantics dimension. Identifier matching is case-insensitive and uses '*' as a multi-character wildcard.","items":{"type":"object","properties":{"effect":{"type":"string","enum":["CLOSED","RESTRICTED","HAZARD","UNSERVICEABLE","WORK_IN_PROGRESS","CAUTION"],"description":"Desired effect."},"type":{"type":"string","enum":["AERODROME","RUNWAY","TAXIWAY","APPROACH","NAVAID","AIRSPACE","APRON","LIGHTING","SERVICE","PROCEDURE","OTHER"],"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*'."},"conditions":{"type":"array","description":"Optional semantics condition clauses. The easiest setup is to copy clauses from interpretation.affected_elements[].semantics.conditions. A supplied clause matches when the affected element has no same-dimension condition or has a compatible same-dimension condition; incompatible same-dimension conditions exclude the NOTAM.","items":{"$ref":"#/components/schemas/AffectedElementClauseFilter"}},"exceptions":{"type":"array","description":"Optional semantics exception clauses. The easiest setup is to copy clauses from interpretation.affected_elements[].semantics.exceptions. A supplied clause matches when the affected element has no same-dimension exception or has a compatible same-dimension exception; incompatible same-dimension exceptions exclude the NOTAM.","items":{"$ref":"#/components/schemas/AffectedElementClauseFilter"}}}}}},"additionalProperties":false},"AffectedElementSubtype":{"type":"string","enum":["ILS_CATEGORY"],"description":"Known affected element subtypes currently emitted by structured interpretations."},"AffectedElementClauseFilter":{"type":"object","properties":{"dimension":{"type":"string","description":"Clause dimension. Required when the clause object is present. Use OPERATIONAL_PHASE with OperationPhaseLiteral values such as TAKEOFF or LANDING, and OPERATIONAL_USE with OperationalUseLiteral values such as ALTERNATE or DESTINATION."},"operator":{"type":"string","description":"Optional clause operator."},"value":{"$ref":"#/components/schemas/AffectedElementClauseValue"},"unit":{"type":"string","description":"Optional clause unit."},"details":{"type":"string","description":"Optional clause details."}}},"AffectedElementClauseValue":{"description":"Structured clause value. Known enum-backed semantics tokens and procedure capability values are listed explicitly; other string/number/boolean/array/object payloads remain allowed for forward compatibility.","anyOf":[{"$ref":"#/components/schemas/IntegerMeasurementValue"},{"$ref":"#/components/schemas/FractionalMeasurementValue"},{"$ref":"#/components/schemas/GroupedMeasurementValue"},{"$ref":"#/components/schemas/ProcedureCapability"},{"$ref":"#/components/schemas/OperationPhaseLiteral"},{"$ref":"#/components/schemas/OperationalUseLiteral"},{"type":"array","items":{"$ref":"#/components/schemas/OperationPhaseLiteral"},"minItems":1},{"type":"array","items":{"$ref":"#/components/schemas/OperationalUseLiteral"},"minItems":1},{"$ref":"#/components/schemas/AffectedElementSemanticToken"},{"type":"array","items":{"$ref":"#/components/schemas/AffectedElementSemanticToken"},"minItems":1},{"type":"array","items":{"type":"string"},"minItems":1},{"type":"string"},{"type":"number"},{"type":"integer"},{"type":"boolean"},{"type":"object","additionalProperties":true}]},"IntegerMeasurementValue":{"type":"object","properties":{"kind":{"type":"string","const":"MEASUREMENT","default":"MEASUREMENT"},"raw_string":{"type":"string"},"value":{"type":"integer"},"unit":{"type":"string"}},"required":["raw_string","value","unit"]},"FractionalMeasurementValue":{"type":"object","properties":{"kind":{"type":"string","const":"FRACTIONAL_MEASUREMENT","default":"FRACTIONAL_MEASUREMENT"},"raw_string":{"type":"string"},"numerator":{"type":"integer"},"denominator":{"type":"integer"},"unit":{"type":"string"}},"required":["raw_string","numerator","denominator","unit"]},"GroupedMeasurementValue":{"type":"object","properties":{"kind":{"type":"string","const":"MEASUREMENTS","default":"MEASUREMENTS"},"raw_string":{"type":"string"},"values":{"type":"array","items":{"$ref":"#/components/schemas/MeasurementComponentValue"}}},"required":["raw_string"]},"MeasurementComponentValue":{"type":"object","properties":{"type":{"type":"string","enum":["ALTITUDE","HEIGHT"]},"value":{"type":"integer"},"unit":{"type":"string"}},"required":["type","value","unit"]},"ProcedureCapability":{"type":"object","properties":{"scheme":{"type":"string","const":"ILS_CATEGORY"},"category":{"type":"string","enum":["CAT_I","CAT_II","CAT_IIIA","CAT_IIIB","CAT_IIIC"]},"level":{"type":"string","enum":["LVL_1","LVL_2","LVL_3"]},"classification":{"type":"string"},"source_label":{"type":"string"}},"required":["scheme"]},"OperationPhaseLiteral":{"type":"string","enum":["TAKEOFF","LANDING","APPROACH","ARRIVAL","DEPARTURE"],"description":"Known semantics values for clauses where dimension is OPERATIONAL_PHASE."},"OperationalUseLiteral":{"type":"string","enum":["ALTERNATE","DIVERSION","DESTINATION","DEPARTURE"],"description":"Known semantics values for clauses where dimension is OPERATIONAL_USE."},"AffectedElementSemanticToken":{"type":"string","enum":["TAKEOFF","LANDING","APPROACH","ARRIVAL","DEPARTURE","LOCAL_FLIGHT","TRAINING_FLIGHT","CIRCUIT","INTERNATIONAL_FLIGHT","FIXED_WING","HELICOPTER","GLIDER","GENERAL_AVIATION","NON_SCHEDULED","NON_COMMERCIAL","SCHEDULED","IFR","VFR","STATE","MILITARY","A","B","C","D","E","F","H","LIGHT","MEDIUM","HEAVY","SUPER","ALTERNATE","DIVERSION","DESTINATION","AVGAS_100","AVGAS_100LL","AVGAS_UL91","JET_A","JET_A1","JET_B","JP_4","JP_5","JP_8","TS_1","MOGAS","HYDRANT","BOWSER","TANKER","FOLLOW_ME","MARSHALLER","PPR","EMERGENCY_FLIGHT","MEDICAL_FLIGHT","SAR_FLIGHT","STATE_FLIGHT","CUSTOMS_OFFICIAL_TRAFFIC","ALS","ALSF_2","SDF","ATIS","DATALINK_CLEARANCE","VGSI","PAPI","VASI","GLIDEPATH","GLIDESLOPE","LOCALIZER","RVR_MEASURING_EQUIPMENT","INNER_MARKER","DME","RADIO_ALTIMETER","RNAV_GPS","RADAR","AUTOPILOT","AIRSHOW","MILITARY_ACTIVITY","BLASTING_ACTIVITY","ROCKET_LAUNCH","UAS_ACTIVITY"],"description":"Known structured semantics literal tokens."},"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"},"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."},"email":{"type":"string","format":"email","description":"Optional email recipient for 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."}},"required":["notams_shipped"]},"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 email is omitted."},"email":{"type":"string","format":"email","description":"Optional email recipient 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). For category, the special value 'all' matches any category. notam_type applies only to normal interpreted deliveries and supports only NOTAMN/NOTAMR (N/R). For affected_element, provide an object describing an effect, a type, a subtype, an identifier, and/or clause filters under conditions and exceptions. The easiest setup is to copy clause objects from interpretation.affected_elements[].semantics. Identifier matching is case-insensitive and uses '*' as a multi-character wildcard. Clause matching is case-insensitive and supports partial clause objects such as dimension-only or dimension+operator filters. Clause filters exclude only explicit same-dimension semantic conflicts; NOTAMs without that semantics dimension still match. 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."},"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","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, clause filters under conditions/exceptions, or any combination of those fields. Interpretations match if ANY of the specified affected element filters match. Within one affected element filter, all provided non-clause fields must match the same affected element. Clause filters exclude explicit same-dimension semantic conflicts but do not require the NOTAM to include that semantics dimension. Identifier matching is case-insensitive and uses '*' as a multi-character wildcard.","items":{"type":"object","properties":{"effect":{"type":"string","enum":["CLOSED","RESTRICTED","HAZARD","UNSERVICEABLE","WORK_IN_PROGRESS","CAUTION"],"description":"Desired effect."},"type":{"type":"string","enum":["AERODROME","RUNWAY","TAXIWAY","APPROACH","NAVAID","AIRSPACE","APRON","LIGHTING","SERVICE","PROCEDURE","OTHER"],"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*'."},"conditions":{"type":"array","description":"Optional semantics condition clauses. The easiest setup is to copy clauses from interpretation.affected_elements[].semantics.conditions. A supplied clause matches when the affected element has no same-dimension condition or has a compatible same-dimension condition; incompatible same-dimension conditions exclude the NOTAM.","items":{"$ref":"#/components/schemas/AffectedElementClauseFilter"}},"exceptions":{"type":"array","description":"Optional semantics exception clauses. The easiest setup is to copy clauses from interpretation.affected_elements[].semantics.exceptions. A supplied clause matches when the affected element has no same-dimension exception or has a compatible same-dimension exception; incompatible same-dimension exceptions exclude the NOTAM.","items":{"$ref":"#/components/schemas/AffectedElementClauseFilter"}}}}}},"additionalProperties":false},"AffectedElementSubtype":{"type":"string","enum":["ILS_CATEGORY"],"description":"Known affected element subtypes currently emitted by structured interpretations."},"AffectedElementClauseFilter":{"type":"object","properties":{"dimension":{"type":"string","description":"Clause dimension. Required when the clause object is present. Use OPERATIONAL_PHASE with OperationPhaseLiteral values such as TAKEOFF or LANDING, and OPERATIONAL_USE with OperationalUseLiteral values such as ALTERNATE or DESTINATION."},"operator":{"type":"string","description":"Optional clause operator."},"value":{"$ref":"#/components/schemas/AffectedElementClauseValue"},"unit":{"type":"string","description":"Optional clause unit."},"details":{"type":"string","description":"Optional clause details."}}},"AffectedElementClauseValue":{"description":"Structured clause value. Known enum-backed semantics tokens and procedure capability values are listed explicitly; other string/number/boolean/array/object payloads remain allowed for forward compatibility.","anyOf":[{"$ref":"#/components/schemas/IntegerMeasurementValue"},{"$ref":"#/components/schemas/FractionalMeasurementValue"},{"$ref":"#/components/schemas/GroupedMeasurementValue"},{"$ref":"#/components/schemas/ProcedureCapability"},{"$ref":"#/components/schemas/OperationPhaseLiteral"},{"$ref":"#/components/schemas/OperationalUseLiteral"},{"type":"array","items":{"$ref":"#/components/schemas/OperationPhaseLiteral"},"minItems":1},{"type":"array","items":{"$ref":"#/components/schemas/OperationalUseLiteral"},"minItems":1},{"$ref":"#/components/schemas/AffectedElementSemanticToken"},{"type":"array","items":{"$ref":"#/components/schemas/AffectedElementSemanticToken"},"minItems":1},{"type":"array","items":{"type":"string"},"minItems":1},{"type":"string"},{"type":"number"},{"type":"integer"},{"type":"boolean"},{"type":"object","additionalProperties":true}]},"IntegerMeasurementValue":{"type":"object","properties":{"kind":{"type":"string","const":"MEASUREMENT","default":"MEASUREMENT"},"raw_string":{"type":"string"},"value":{"type":"integer"},"unit":{"type":"string"}},"required":["raw_string","value","unit"]},"FractionalMeasurementValue":{"type":"object","properties":{"kind":{"type":"string","const":"FRACTIONAL_MEASUREMENT","default":"FRACTIONAL_MEASUREMENT"},"raw_string":{"type":"string"},"numerator":{"type":"integer"},"denominator":{"type":"integer"},"unit":{"type":"string"}},"required":["raw_string","numerator","denominator","unit"]},"GroupedMeasurementValue":{"type":"object","properties":{"kind":{"type":"string","const":"MEASUREMENTS","default":"MEASUREMENTS"},"raw_string":{"type":"string"},"values":{"type":"array","items":{"$ref":"#/components/schemas/MeasurementComponentValue"}}},"required":["raw_string"]},"MeasurementComponentValue":{"type":"object","properties":{"type":{"type":"string","enum":["ALTITUDE","HEIGHT"]},"value":{"type":"integer"},"unit":{"type":"string"}},"required":["type","value","unit"]},"ProcedureCapability":{"type":"object","properties":{"scheme":{"type":"string","const":"ILS_CATEGORY"},"category":{"type":"string","enum":["CAT_I","CAT_II","CAT_IIIA","CAT_IIIB","CAT_IIIC"]},"level":{"type":"string","enum":["LVL_1","LVL_2","LVL_3"]},"classification":{"type":"string"},"source_label":{"type":"string"}},"required":["scheme"]},"OperationPhaseLiteral":{"type":"string","enum":["TAKEOFF","LANDING","APPROACH","ARRIVAL","DEPARTURE"],"description":"Known semantics values for clauses where dimension is OPERATIONAL_PHASE."},"OperationalUseLiteral":{"type":"string","enum":["ALTERNATE","DIVERSION","DESTINATION","DEPARTURE"],"description":"Known semantics values for clauses where dimension is OPERATIONAL_USE."},"AffectedElementSemanticToken":{"type":"string","enum":["TAKEOFF","LANDING","APPROACH","ARRIVAL","DEPARTURE","LOCAL_FLIGHT","TRAINING_FLIGHT","CIRCUIT","INTERNATIONAL_FLIGHT","FIXED_WING","HELICOPTER","GLIDER","GENERAL_AVIATION","NON_SCHEDULED","NON_COMMERCIAL","SCHEDULED","IFR","VFR","STATE","MILITARY","A","B","C","D","E","F","H","LIGHT","MEDIUM","HEAVY","SUPER","ALTERNATE","DIVERSION","DESTINATION","AVGAS_100","AVGAS_100LL","AVGAS_UL91","JET_A","JET_A1","JET_B","JP_4","JP_5","JP_8","TS_1","MOGAS","HYDRANT","BOWSER","TANKER","FOLLOW_ME","MARSHALLER","PPR","EMERGENCY_FLIGHT","MEDICAL_FLIGHT","SAR_FLIGHT","STATE_FLIGHT","CUSTOMS_OFFICIAL_TRAFFIC","ALS","ALSF_2","SDF","ATIS","DATALINK_CLEARANCE","VGSI","PAPI","VASI","GLIDEPATH","GLIDESLOPE","LOCALIZER","RVR_MEASURING_EQUIPMENT","INNER_MARKER","DME","RADIO_ALTIMETER","RNAV_GPS","RADAR","AUTOPILOT","AIRSHOW","MILITARY_ACTIVITY","BLASTING_ACTIVITY","ROCKET_LAUNCH","UAS_ACTIVITY"],"description":"Known structured semantics literal tokens."},"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"},"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."},"email":{"type":"string","format":"email","description":"Optional email recipient for 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."}},"required":["notams_shipped"]},"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: 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.
