Skip to main content

Filtering

Filters narrow the stream to only the aircraft you care about. They run server-side, so a tight filter reduces both bandwidth and per-batch processing on your client.

Filters apply at the moment a stream is opened and stay in effect for the duration of that session. To change what you receive, update the filter and reopen the stream — either by calling SubscriptionService.UpdateSubscription and reconnecting, or by passing a new filter when opening the next stream (depending on your client library).

Filter shape

A filter is a JSON document with a single root_group. A group combines a logical_operator with a list of leaf conditions and optional nested sub-groups:

{
"root_group": {
"logical_operator": "and",
"conditions": [
{ "property": "alt_baro", "operator": "lt", "value": "5000" }
],
"groups": []
}
}

A group has:

FieldDescription
logical_operatorand or or — how the entries below are combined.
conditionsArray of leaf conditions (see below).
groupsArray of nested sub-groups, each itself a group with the same shape.

A condition has:

FieldDescription
propertyThe aircraft JSON field name (e.g. alt_baro, hex, flight, gs). See Aircraft for the full list.
operatorOne of the comparison operators listed below.
valueThe value to compare against, as a string (numeric values are accepted as numeric strings).

Operators

OperatorDescription
eqEquals
neNot equals
gtGreater than
geGreater than or equal
ltLess than
leLess than or equal
containsString contains (case-insensitive)
notcontainsString does not contain
startswithString starts with
notstartswithString does not start with
endswithString ends with
notendswithString does not end with
isnullProperty is missing or null
isnotnullProperty is present and not null

String comparisons are case-insensitive. Numeric comparisons apply to fields whose values are numbers (alt_baro, gs, lat, lon, etc.). For alt_baro, the value "ground" is treated as 0 — so alt_baro lt 1000 will include grounded aircraft.

Examples

Aircraft below 5,000 ft

{
"root_group": {
"logical_operator": "and",
"conditions": [
{ "property": "alt_baro", "operator": "lt", "value": "5000" }
]
}
}

Airborne aircraft below 5,000 ft moving faster than 100 kt

Combines two conditions with and. Useful for excluding stationary or taxiing aircraft from a low-altitude filter.

{
"root_group": {
"logical_operator": "and",
"conditions": [
{ "property": "alt_baro", "operator": "lt", "value": "5000" },
{ "property": "alt_baro", "operator": "ne", "value": "ground" },
{ "property": "gs", "operator": "gt", "value": "100" }
]
}
}

Specific aircraft by ICAO hex

{
"root_group": {
"logical_operator": "or",
"conditions": [
{ "property": "hex", "operator": "eq", "value": "a1b2c3" },
{ "property": "hex", "operator": "eq", "value": "d4e5f6" }
]
}
}

Nested groups: heavy aircraft OR fast aircraft

Use the groups array on a parent group to combine sub-expressions with mixed and/or. Here: aircraft categorised as heavy (category A5), or any aircraft above Mach 0.85.

{
"root_group": {
"logical_operator": "or",
"groups": [
{
"logical_operator": "and",
"conditions": [
{ "property": "category", "operator": "eq", "value": "A5" }
]
},
{
"logical_operator": "and",
"conditions": [
{ "property": "mach", "operator": "gt", "value": "0.85" }
]
}
]
}
}

Aircraft type code matches a pattern

{
"root_group": {
"logical_operator": "and",
"conditions": [
{ "property": "t", "operator": "startswith", "value": "B7" }
]
}
}

Matches Boeing 7-series types (B737, B738, B744, B777, B788, etc.).

How to apply a filter

Call SubscriptionService.UpdateSubscription with the filter on the request, then open a new stream — the filter applies to subsequent StartStream calls.

Field name mapping

The protobuf wire shape uses slightly different field names than the examples above:

In examples aboveOn the wire (proto JSON)
root_grouprootGroup
logical_operatorop (with values "AND" or "OR")
propertyfield
operatorop

Full grpcurl invocation that applies the "below 5,000 ft" filter from the first example:

grpcurl \
-import-path . -proto subscription.proto \
-H "client-id: <YOUR_CLIENT_ID>" \
-d '{
"subscriptionId": "<YOUR_SUBSCRIPTION_ID>",
"filters": {
"rootGroup": {
"op": "AND",
"conditions": [
{ "field": "alt_baro", "op": "lt", "value": "5000" }
]
}
}
}' \
stream.adsbexchange.com:443 \
jetnet.streaming.SubscriptionService/UpdateSubscription

The server responds with the updated Subscription message confirming the change. Reconnect your stream to start receiving filtered data.