API Documentation
Full API Documentation: https://docs.firewalla.net
Examples: https://github.com/firewalla/msp-api-examples
Note: Our API may change slightly for a while as we refine it in response to feedback. Be aware of that as you use it. Any changes that are made will be reflected in the API Documentation.
Note, "box" in this document refers to a Firewalla box, and "device" refers to clients that are connected on the network managed by a Firewalla box.
Summary Table
- Authentication
- List Boxes
- List Devices
- Device Details
- Alarm List
- Alarm Detail
- Archive Alarm
- Delete Alarm
- Flows
Helpful Tools
- https://jqplay.org Very helpful in testing jq selections and filters.
- https://www.unixtimestamp.com to convert timestamps from standard to epoch format and back.
- https://www.postman.com is a tool that you can use to make repeating the API calls much easier.
Authentication
Go to Account Settings (1) and Create New Token (2) and give your token a name (3). You may want to create different tokens for different purposes so that you can disable a token if needed without affecting other uses of the token.
Your token will appear. Keep in mind that you can't see this token again, so keep it safe. You can always generate more tokens though. And, very importantly, you can invalidate a token if you ever think it has been compromised by deleting the token.
Now let's go through a few examples of what you can do with the Firewalla MSP API.
Examples
List Boxes
curl
to make our API calls and jq
to format and filter the results because they are available for nearly every platform.Sample Request - Get list of boxes
curl --request GET \
--url 'https://[yourMSP].firewalla.net/v1/box/list' \
--header 'Authorization: Token 0868yourtokend3a'
Sample Response
[
{
"name": "Purple",
"model": "purple",
"gid": "c86e91b3-a710-4af",
"eid": "VVCx8jF_kRzeVzY",
"version": "1.9735",
"firstBinding": 1645877840.766,
"publicIp": "130.31.187.3",
"mode": "router",
"location": "Santa Clara, US",
"status": true,
"activeTs": 1649318408.853,
"syncTs": 1649318222,
"lokiEnabled": true
},
{
"name": "Gold",
"model": "gold",
"gid": "78b5986d-35c9-475c",
"eid": "daEILX1N7iu",
"version": "1.974",
"firstBinding": 1598308161.715,
"publicIp": "122.50.187.3",
"mode": "router",
"location": "Santa Clara, US",
"status": true,
"activeTs": 1649318408.959,
"syncTs": 1649318226,
"lokiEnabled": true
}
]
In this MSP instance, we have two Firewalla boxes; "Gold" and "Purple".
Callouts
gid
is the box ID. You will need this for several other APIs as we will see later.- Timestamps like
firstBinding
are in epoch time and use UTC. Calculate accordingly. - There is also a lot of other great information about each box.
If you need info about just one box, you could use jq
or something similar to filter the result as below:
Sample Request - Filter box info for just one box
curl --request GET --url 'https://[yourMSP].firewalla.net/v1/box/list' \
--header 'Authorization: Token 086yourtokend3a' | jq '.[] | select(.name=="Gold")'
which returns only info for the device named, "Gold" already shown previously. There are lots of great jq tutorials you can find to help you navigate all kinds of searches and filters.
List Devices
Now let's see how to get a list of devices.
Sample Request - Get a list of devices
curl --request GET --url 'https://[yourMSP].firewalla.net/v1/device/list'
--header 'Authorization: Token 086yourtokend3a'
Sample Response (partial)
For brevity, this shows just the first of many devices that are associated across all the boxes in this MSP instance.
[
{
"ip": "192.168.224.90",
"mac": "14:98:77:",
"lastActive": "1649267746.665",
"firstFound": "1646159412.379",
"macVendor": "Apple, Inc.",
"bname": "BigMac",
"names": [
"BigMac"
],
"policy": {
"monitor": true,
"ipAllocation": {
"allocations": {
"a4641070-cfbf-4902-85ba-24e0765ab3f6": {
"type": "dynamic"
}
},
"dhcpIgnore": false
},
"device_service_scan": false,
"tags": [],
"acl": true,
"deviceOffline": false,
"devicePresence": false,
"doh": {
"state": false
},
"family": false,
"safeSearch": {
"state": false
},
"adblock": false,
"vpnClient": {
"state": false
}
},
"intf": {
"uuid": "a4641070-cfbf",
"name": "LAN 1"
},
"name": "BigMac",
"reserved": f alse,
"totalUpload": 848825415,
"totalDownload": 975502160,
"gid": "c86e91b3-a710-4af5",
"online": false
},
...
]
If you wanted to only get a list of all device names (without all the other metadata) you could do this:
Sample Request - Get a list of device names only (strip out all other data)
curl --request GET \
--url 'https://[yourMSP].firewalla.net/v1/device/list' \
--header 'Authorization: Token 086yourtokend3a' | jq '.[].name'
gid
mentioned previously, comes in. The following request would, as above, start by getting all the devices in your MSP instance, but then filter only the devices associated with the box with gid
, "78b5986d-35c9-475c-ae89-0d899a1a7059". Sample Request - Get all devices associated with a specific box
curl --request GET --url 'https://[yourMSP].firewalla.net/v1/device/list' \
--header 'Authorization: Token 0868cyourtokenb6cd3a' \
| jq '.[] | select(.gid=="78b5986d-35c9-475c-ae9")'
Sample Request - Get all devices with a reserved IP
curl --request GET --url 'https://[yourMSP].firewalla.net/v1/device/list' \
--header 'Authorization: Token 086yourtokend3a' | \
jq '.[] | select(.reserved == true) | "\(.name), \(.ip), \(.mac), Reserved:\(.reserved)"'
- all devices, filtered by those that have reserved IP addresses
- Output only the name, IP, and that reserved status
Sample Response
"BigMac WiFi 🖥, 192.168.0.41, cb:7e:44:04:ce:6e, Reserved True"
"unifi AP: Living room 📶, 192.168.110.4, :26:42:91, Reserved True"
"neurio ⚡️, 192.168.133.33, 2:8b:f6, Reserved True"
"ASUS WAN, 192.168.166.2, b2:16, Reserved True"
"unifi Switch: Living Room 🔀, 192.168.110.9, 18:cd:3b:ef, Reserved True"
"unifi AP: Backyard 📶, 192.168.110.6, :59:9A:02, Reserved True"
"unifi AP:Garage 📶, 192.168.110.7, :fd:cf:1c, Reserved True"
"unifi AP: Bedroom 📶, 192.168.110.5, 4:2a:f1:be, Reserved True"
"Old Coke Ethernet 💻, 192.168.0.30, :55:c6:2c, Reserved True"
"unifi Switch: Office 🔀, 192.168.110.10, :9c:7d:35:03, Reserved True"
"Old Coke WiFi 🖥, 192.168.0.31, 0a:19:6e, Reserved True"
"BigMac Ethernet 🖥, 192.168.0.40, a5:1c:99:f2, Reserved True"
"Firewalla Purple Ethernet WAN🔥, 192.168.177.2, 60:c3:6e:80, Reserved True"
"Brother Printer MFC-8910DW 🖨, 192.168.144.4, 1:9d:64:4f, Reserved True"
Sample Request - Get list of Groups
curl --request GET --url 'https://[yourMSP].firewalla.net/v1/device/list' \
--header 'Authorization: Token 086yourtokend3a' \
| jq 'unique_by(.tags[0].name) | .[] | .tags[0].name | select (. != null )'
Here we exclude devices that are not assigned to a Group because we only want a list of the Groups.
Sample Response
"Apple TVs"
"Girls"
"Homeboy"
"Laury"
"Michael"
"Network devices"
"Samsung TVs"
"Smart life"
"nest"
Sample Request - Get a list of devices assigned to a Group
To get all device names in the Group name, "Michael"
curl --request GET --url 'https://[yourMSP].firewalla.net/v1/device/list' \
--header 'Authorization: Token 086yourtokend3a' \
| jq '.[] | select (.tags[0].name == "Michael" ) | .name'
| .name
we would have gotten all of the data for every device. For brevity, we just asked for the device name.Sample Response
"M’s MacBoook Pro 💻"
"M’s iPhone 📱"
"BigMac Ethernet 🖥"
"Old Coke Ethernet 💻"
"M’s iPad 📋"
"BigMac WiFi 🖥"
"Old Coke WiFi 🖥"
"M’s Apple Watch ⌚️"
What if we wanted a list of devices that are not in a Group?
Sample Request - Get list of devices not in a Group
curl --request GET --url 'https://[yourMSP].firewalla.net/v1/device/list' \
--header 'Authorization: Token 086yourtokend3a' | \
jq '.[] | select (.tags[0] | .==null or . == "") | "\(.name), \(.ip)"'
Device Details
To get the device details, we once again need the gid
of the box which from box/list
and the mac
address which you could get from device/list
. This makes sense because it is possible that a device could have joined more than one Firewalla at some point. So we need to specify both the box and the device we are after.
Sample Request - Get device details
curl --request GET \
-url 'https://[yourMSP].firewalla.net/v1/device/78b5986d-3-0d899a1a7059/i3:D0:86:A0' \
--header 'Authorization: Token 086yourtokend3a'
Sample Response (Partial)
The response for a device is quite long, so this is just an except.
[
{
"name": "Old Coke Ethernet 💻",
"ip": "192.168.0.30",
"mac": "i3:D0:86:A0",
"gid": "78b5986d-39a1a7059",
"intf": {
"uuid": "4373ca09--8ab0-dc07443f04a3",
"name": "LAN 0"
},
"macVendor": "Apple",
"online": true,
"totalDownload": 12084445,
"totalUpload": 99937,
"reserved": true,
"lastActive": "1649358162.921",
"firstFound": "1598859336.803",
"tags": [
{
"name": "Michael",
"uid": "3"
}
],
"localDomain": "old.coke.ethernet",
"localDomainSuffix": "lan",
"last12Months": {
"upload": [
[
1620000000,
5593667481
],
...
]
Alarm List
First, let's see how to grab a list of up to the 50 most active alarms for each box.
Sample Request - Get 50 most active alarms for all boxes
curl --request GET --url 'https://[yourMSP].firewalla.net/v1/alarm/list' \
--header 'Authorization: Token 086yourtokend3a'
Sample Response (partial)
The full response can be quite long, so this is just an excerpt.
[
{
"p.iface.name": "WAN: Wi-Fi ",
"p.message": "Internet connectivity on WAN: Wi-Fi has been restored. Active WAN is switched to WAN: Wi-Fi .",
"p.showMap": "false",
"p.active.wans": "[\"WAN: Wi-Fi \"]",
"aid": "306",
"p.cloud.decision": "alarm",
"p.fi": "40",
"alarmTimestamp": "1649333768.581",
"device": "WAN: Wi-Fi ",
"p.wan.switched": "true",
"timestamp": "1649333768.581",
"type": "ALARM_DUAL_WAN",
"message": "INFO_ALARM_DUAL_WAN",
"p.ready": "true",
"p.wan.type": "primary_standby",
"gid": "c86e91b3-a-88e106aeffd1"
},
...
]
Callouts
aid
is the alarm ID. We'll see how to use that in later examples.
gid
, so we can filter the alarms for just a specific box if we need to.Sample Request - Get 50 most active alarms for a specific box
curl --request GET --url 'https://[yourMSP].firewalla.net/v1/alarm/list' \
--header 'Authorization: Token 086yourtokend3a' \
| jq '.[] | select(.gid=="c86e91b3-a-88e106aeffd1")'
Or we can specify we want the alarms from two boxes
Sample Request - Get 50 most active alarms for specific boxes
curl --request GET --url 'https://[yourMSP].firewalla.net/v1/alarm/list' \
--header 'Authorization: Token 086yourtokend3a' \
| jq '.[] | select(.gid=="c86e91b3-a-88e106aeffd1" or .gid=="c-ae89-0d899a1a7059")'
Now let's get info on alarms within a specific window of time.
Sample Request - Get Alarms within a specific timeframe
Let's walk through this more complex example.
- Get an alarm list...
- sorted by the time of the alarm... (optional)
- and after Wednesday, March 30, 2022 9:49:43 PM and before Wednesday, March 30, 2022 9:59:33 PM
- and instead of all of the output, we asked for just the timestamp of the device and the device name.
curl --request GET --url 'https://[yourMSP].firewalla.net/v1/alarm/list' \
--header 'Authorization: Token 086yourtokend3a' | \
jq 'sort_by(.alarmTimestamp) | .[] \
| select ( .alarmTimestamp >= "1648676983" and .alarmTimestamp <= "1648677573" ) | \
"\(.alarmTimestamp), \(.device)"'
Sample Response
"1648676983.428, BIGMAC"
"1648676983.803, ASUSTek COMPUTER INC."
"1648677571.841, Unknown"
This technique can be used to filter output from all of the endpoints that don't have a way of bracketing the window of data you want to see.
We could modify the same request slightly to show all of the alarms for two devices between a certain time like this:
curl --request GET --url 'https://[yourMSP].firewalla.net/v1/alarm/list' \
--header 'Authorization: Token 086yourtokend3a' | \
jq 'sort_by(.alarmTimestamp) | .[] | \
select ((.device == "Jovanas-iPad" or .device == "Michael’s iPad 📋") and \
.alarmTimestamp >= "1649383062") | "\(.alarmTimestamp), \(.device)" '
- Give an alarm list for two iPads...
- sorted by the time of the alarm... (optional)
- and after Wednesday, March 30, 2022 9:49:43 PM
- and instead of all of the output, we asked for just the timestamp of the device and the device name.
Sample Response
"1649383062.184, J-iPad"
"1649383542.747, J-iPad"
"1649415486.825, M’s iPad 📋"
Now let's get just one type of alarm for all devices on a specific box.
Sample Request - Get just one alarm type
curl --request GET --url 'https://[yourMSP].firewalla.net/v1/alarm/list' \
--header 'Authorization: Token 086yourtokend3a' | \
jq '.[] | \
select(.gid=="475c-ae89-0d899a1a7059" and .type=="ALARM_DUAL_WAN") '
If we omitted the .gid=="475c-ae89-0d899a1a7059"
from the statement, we would have gotten all of the Dual_WAN alarms
for all boxes. This could allow us to see if we are seeing a lot of connection drops and on which boxes.
Sample Response (partial)
{
"p.cloud.decision": "alarm",
"type": "ALARM_DUAL_WAN",
"p.wan.type": "primary_standby",
"message": "INFO_ALARM_DUAL_WAN",
"aid": "23186",
"alarmTimestamp": "1649506415.428",
"p.message": "Internet connectivity on SaIl Internet has been restored. Active WAN is switched to SaIl Internet.",
"p.active.wans": [
"SaIl Internet"
],
"p.ready": "true",
"p.iface.name": "SaIl Internet",
"timestamp": "1649506415.428",
"device": "SaIl Internet",
"p.fi": "40",
"p.showMap": "false",
"p.wan.switched": "true",
"gid": "475c-ae89-0d899a1a3032"
}
...
Alarm Detail
So now let's get details for a specific alarm using the gid
and the aid
from the previous example.
Sample Request - Alarm detail
curl --request GET --url \
'https://[yourMSP].firewalla.net/v1/alarm/475c-ae89-0d899a1a3032/23186'\
--header 'Authorization: Token 086yourtokend3a'
Callouts
Here we use:
- the
gid
to specify the box we are interested in and - the specific
aid
to specify the alarm ID we are interested in.
Sample Response
"alarm"
"ALARM_DUAL_WAN"
"primary_standby"
"INFO_ALARM_DUAL_WAN"
"23186"
"1649506415.428"
"Internet connectivity on SaIl Internet has been restored. Active WAN is switched to SaIl Internet."
[
"SaIl Internet"
]
"true"
"SaIl Internet"
"1649506415.428"
"SaIl Internet"
"40"
"false"
"true"
"78b5986d-35c9-475c-ae89-0d899a1a7059"
Archive Alarm
You can also use the API to archive alarms. For this, you will need the gid
(device ID) and aid
(alarm ID) we found earlier.
Sample Request - Archive an alarm
curl --request POST \
--url 'https://[yourMSP].firewalla.net/v1/alarm/archive/c86e91b3-a-88e106aeffd1/306' \
--header 'Authorization: Token 086yourtokend3a'
Sample Response
{
"message": "success",
"success": true
}
Delete Alarm
gid
(device ID) and aid
(alarm ID) we found earlier. Sample Request - Delete an alarm
curl --request POST \
--url 'https://[yourMSP].firewalla.net/v1/alarm/delete/c86e91b3-a-88e106aeffd1/306' \
--header 'Authorization: Token 086yourtokend3a'
Sample Response
{
"message": "success",
"success": true
}
Flows
Sample Request - Archive an alarm
curl --request POST \
--url 'https://[yourMSP].firewalla.net/v1/flows/query' \
--header 'Content-Type: application/json' \
--header 'Authorization: Token 086yourtokend3a' \
--data '{
"limit": 200,
"start": 1647832113,
"end": 1647882113,
"filters": [
{
"key": "device",
"values": [
"Gold"
]
}
]
}'
Callouts
limit
is the maximum number of records that will be returned.start
andend
are timestamps which must be in epoch format.Key
can be device, source, group, destination, network, direction, status, blocked by, or country.Values
can be any number of delimited things that match the Key. For example, five devices or three Groups. For example:
curl --request POST \
--url 'https://[yourMSP].firewalla.net/v1/flows/query' \
--header 'Content-Type: application/json' \
--header 'Authorization: Token 086yourtokend3a' \
--data '{
"limit": 200,
"start": 1647832113,
"end": 1647882113,
"filters": [
{
"key": "group",
"values": [
"Michael", "Girls", "nest"
]
}
]
}'
This translates to, "Give me the up to 200 Flow records between the timestamps for the Groups: Michael, Girls, and nest."
By default the API returns 200 responses. If you need more or less than, that you can specify like so:
curl --request POST \
--url 'https://your_instance_name.firewalla.net/v1/flows/query' \
--header 'Authorization: Token [your token]' \
--header 'Content-Type: application/json' \
--data '{ "limit": 300, "start": 1677613186, "end": 1677631186}'
The start/end times are in unix epoch format are optional, but give you bracket precisely the time inspected.
Summary
Using the Firewalla MSP API you can create even more powerful alerts and reports, query your Firewalla boxes, look for things in a way that is very hard for Firewalla to build into any interface. You can really fashion your own integrations into internal apps in powerful ways.
Community Examples:
https://github.com/firewalla/msp-api-examples
Comments
9 comments
I see these are all GET requests. What about POST requests. I would love the ability to add ip/domain names to a target list from outside the UI. For instance, running a web server and wanted to block some ip addresses I catch trying to access a page they are not supposed to. Or someone trying to break into my SSH server, I would love to process the log file on another computer and send it to the firewalla to block them from ALL devices and not just the one (Automatically).
We will likely to expose some of the rules API's for sure in the future.
I assume you want
1. Add/modify to target list
2. Apply rules (block / allow)
Yes to both of those.
Let’s encourage the team to share their progress one sprint at a time. If we knock what “isn’t” rather than appreciate what “is” and thank them we seem ungrateful.
People need to understand the development process.
I would love to see the ability to create, delete, resume, pause rules as well via API. My primary purpose is to use it to dynamically manage my kid's screen time.
I'm interested in that too - there could be a huge market for people (and therefore apps) looking to manage kid's screen time at the network level. I'm interested in helping to beta test this, along with several other families who have expressed interest.
I suggest that whenever
jq
is used that that.ts
is converted to local time for ease of reading. For example:Firewalla team, it's being almost a year now, to expose these endpoints should be no brainer. Create and manage rules in the application IS minimum, annoying. Thank you!
Any news on api support for rules (at least pause/resume)?
Please sign in to leave a comment.