# Searching

# Basic Query Syntax

The query has the same syntax with query string on MSP web UI, the syntax is illustrated below:

query = search-term [ " " search-term ]*
search-term = literal-search | numeric-search
literal-search = [ [ "-" ] qualifier ":" ] literal-match
qualifier = <property-path> | <property-alias>
literal-match = literal [ "," literal ]*
literal = <string> | <quoted-string>
numeric-search = qualifier ":" numeric-match
numeric-match = [ ">" | ">=" | "<" | "<=" ] <number> [ <unit> ] | <number> [ <unit> ] "-" <number> [ <unit> ]
  • Each query is composed by one or multiple space-seperated search-term.
  • Each search-term represents one condition that the result has to meet. It's either a literal-search or a numeric-search
  • IMPORTANT The query string must be URL encoded on sending

An example for a full query

box.name:"Gold Plus",Purple mac:"AA:BB:CC:DD:EE:FF" Total:>50MB

# Qualifier

A qualifier specifies the property that supposed to be matched with the match provided. It could be represented in form of a dot-seperated path, like device.name, which follows the data model of resource being searched. A pre-defined alias could also be used as qualifier. Alias is case insensitive. Not all properties has alias.

A search-term without qualifier is an unqualified search. It searches across a subset of properties. The subset being searched is listed with each resource type.

# Literal Search

A literal search by default checks if a property value equals to the literal provided. Multiple literals could be provided with , in between. Results matching either of them are returned. Literal search works only on string properties. Literal search is case sensitive.

# Wildcard

The wildcard * could be used to perform a fuzzy search, which could come handy in various ways. For example, device.name:*iphone* returns iphone-12, joe-iphone, and any other device that name contains iphone. However, because of performance issue, neither unqualified search nor exclusive search is currently supported with wildcard.

# Quoted Search

To search for a string that contains whitespace , * :, the string has to be quoted with double quotes "". For example:

box:"Firewalla GSE","Firewalla,GSE"

To search for a string that contains " \ *, the string has to be quoted and all " \ * in string has be to escaped with a backslash \. For example

box:"\"fire","Fire\\walla:GSE","Firewalla Gold\*"

# Exclusive Search

You can narrow down search results by excluding one or more subsets. To exclude all results that are matched by a search-term, prefix it with a hyphen -. For example, the following statement excludes any alarms with the status 'active'

-status:active

# Numeric Search

A numeric search by default checks if a property value matches a specific mathmatical relation to the number provided. By default it checks for equality, while > >= < or <= could be inserted before the number to denote other relations.

Numeric search only works for numeric properties. It supports neither unqualified search nor exclusive search.

Operator Description
:< Less than, only works for numeric properties,
download:<10KB or download:<10000
:> Greater than, only works for numeric properties
upload:>10KB or upload:>10000
:<= Less than or equal to, only works for numeric properties,
download:<=10KB or download:<=10000
:>= Greater than or equal to, only works for numeric properties
upload:=>10KB or upload:=>10000
# Range Search

You can use the range syntax n-m to search for values within a range, where the first number n is the lower bound and the second one m is the higher bound. e.g. download:1000-2000 or ts:1695196894.395-1695604487.633

# Unit

Some property could be searched with a suffixed unit. The available units and convention is documented with corresponding property.

# Pagination

Instead of returning a huge chunk of data in a request, pagination divides and returns data to clients in smaller batches, which is easier for both sides to deal with. Every paged response, except the last one, is returned with a base64 encoded next_cursor. And every request, except the very first one, is required to set cursor with corresponding value returned from server earlier.

Example

const params = {
    query: `status:active box:${box}`,
    cursor: null,
    limit: 10
}
const alarms = [];

while (1) {
    const { results, next_cursor } = await httpClient({
        method: 'get',
        url: `/alarms`,
        params: params
    }).then(r => r.data);
    alarms.push(...results);
    if (!next_cursor) break;
    params.cursor = next_cursor;
}

# Alarm Qualifiers

You can search Alarm with the following qualifiers.

Qualifier Example and Addiontal Notes
ts ts:<1695196894.395
The timestamp of alarm. This is usually used together with sortBy to perform a desired search
type
alias: AlarmType
type:1,2,3
AlarmType:"Security Activity,Abnormal Upload,Large Bandwidth Usage"
status status:active
box.id box.id:00000000-0000-0000-0000-000000000000
the box object is not returned in the search result while only gid (box.id) is returned, this is by design
box.name
alias: Box
box.name:FirewallaGold
box.group.id box.group.id:1 the unique id of the msp group
device.id
alias: Mac
device.id:"mac:AA:BB:CC:DD:EE:FF"
device.name
alias: Device
device.name:iphone
device.network.id device.network.id:00000000-1111-1111-1111-000000000000
device.network.name
alias: Network
device.network.name:Guest
remote.category
alias: Category
remote.category:porn,game
remote.domain
alias: Domain
remote.domain:google.com
remote.region
alias: Region
remote.region:US
transfer.download
alias: Download
transfer.download:>10MB
Available Units
transfer.upload
alias: Upload
transfer.upload:>10MB
Available Units
transfer.total
alias: Total
transfer.total:>50MB
Available Units

# Flow Qualifiers

You can search Flow with the following qualifiers.

Qualifier Example and Addiontal Notes
ts ts:<1695196894.395
The timestamp of flow. This is usually used together with sortBy to perform a desired search
status status:ok
direction direction:outbound
box.id box.id:00000000-0000-0000-0000-000000000000
the box object is not returned in the search result while only gid (box.id) is returned, this is by design
box.name
alias: Box
box.name:FirewallaGold
box.group.id box.group.id:1 the unique id of the msp group
device.id
alias: Mac
device.id:"mac:AA:BB:CC:DD:EE:FF"
device.name
alias: Device
device.name:iphone
network.id network.id:00000000-1111-1111-1111-000000000000
network.name
alias: Network
network.name:Guest
category
alias: Category
category:porn,game
domain
alias: Domain
domain:google.com
region
alias: Region
region:US
sport
alias: SourcePort
sport:123
dport
alias: DestinationPort
dport:123
download
alias: Download
download:>10MB
Available Units
upload
alias: Upload
upload:>10MB
Available Units
total
alias: Total
total:>50MB
Available Units

# Rule Qualifiers

You can search Rule with the following qualifiers.

Qualifier Example and Addiontal Notes
status status:active
action action:block
box.id box.id:00000000-0000-0000-0000-000000000000
the box object is not returned in the search result while only gid (box.id) is returned, this is by design
box.group.id box.group.id:1
the unique id of the msp group
device.id device.id:"AA:BB:CC:DD:EE:FF"
the device object is not returned in the search result while only nested object scope:{"type":"device","value":"AA:BB:CC:DD:EE:FF"} is returned, this is by design

# Units

 B (Byte)
KB (KiloByte) = 1000 B
MB (MegaByte) = 1000 KB 
GB (GigaByte) = 1000 MB
TB (TeraByte) = 1000 GB