NAV
shell

General Information

Welcome to the Firefly API v1 documentation. This documentation is a work in progress. If anything is unclear or undocumented, please reach out to us at support@digimondo.de.

Firefly API Documentation URL

  GET "https://apidocs.fireflyiot.com"

The Firefly APIv1 documentation is located at https://apidocs.fireflyiot.com.

Firefly APIv1 URL

  GET "https://api.fireflyiot.com/api/v1"

The Firefly APIv1 is located at https://api.fireflyiot.com/api/v1.

Using the REST API

For the HTTP methods PUT and POST you have to pass

Content-Type: application/json

in the request headers.

Authentication

Authentication by API Key

To authorize, use the auth parameter:

# With shell, you can just pass the correct header with each request
curl "https://api.fireflyiot.com/api/v1/devices?auth=secretapikey"

Firefly uses API keys to allow access to the API.

Firefly expects for the API key to be included in all API requests to the server as a HTTP parameter named auth:

auth=secretapikey

API keys are issued for an organization. They allow access to all resources of that organization and its sub-organizations.

API keys expire after a certain amount of time. The Firefly web interface allows administrators to revoke and renew API keys.

Rate Limiting

General Information

API access is rate-limited per API key to 50 requests over a period of 10 seconds. This is the default value, a change can be requested. In case of surpassing the maximum amount of allowed API calls, a 429 HTTP code will be returned. A wait time before retrying should be implemented, preferably with exponential back-off.

HTTP Response Headers

Every response will include the following three header fields:

x-ratelimit-limit: 50/10000ms
x-ratelimit-reset: 7998
x-ratelimit-remaining: 44
Field Type Description
x-ratelimit-limit String The actual rate limit in the form of “50/10000ms”, meaning 50 requests allowed over a span of 10000 milliseconds
x-ratelimit-remaining Integer The number of remaining requests that are allowed within the current rate limit window
x-ratelimit-reset Integer The number of milliseconds left in the current rate limit window

Make sure you don’t send requests to the API when x-ratelimit-remaining is at 0. In that case, wait x-ratelimit-reset milliseconds before attempting the next request.

Show Rate Limit Details

curl "https://api.fireflyiot.com/api/v1/rate_limit?auth=secretapikey"

This REST endpoint can be used to check the current rate limits for your API key. Calling this endpoint will not count against the rate limits for the key used.

{
  "rate_limit":{
    "remaining": 48,
    "reset": 1234,
    "limit": "50/10000ms"
  },
  "valid_for_key": "secretapikey"
}
Field Type Description
rate_limit.limit String The actual rate limit in the form of “50/10000ms”, meaning 50 requests allowed over a span of 10000 milliseconds
rate_limit.remaining Integer The number of remaining requests that are allowed within the current rate limit window
rate_limit.reset Integer The number of milliseconds left in the current rate limit window
valid_for_key String The API key for which these rate limit values are valid

Devices

A device is a sensor or appliance which is capable of receiving and/or transmitting LoRaWAN packets. Every device is assigned a unique EUI. Depending on the mode of initial authentication, a device address might be assigned.

Show All Devices

Sample request

GET "https://api.fireflyiot.com/api/v1/devices?auth=secretapikey"

Sample response

{
  "devices": [
    {
      "updated_at": "2016-05-25T09:02:41.307000",
      "otaa": false,
      "network_session_key": "3C0FD994269EA89AEDDDDDCF55ADDD68",
      "eui": "00000000AABBCCDD",
      "name": "Device #1",
      "description": "The Device with #1",
      "inserted_at": "2016-05-20T13:51:04.643000",
      "application_session_key": "3C0FD994269EA89AEDDDDDCF55ADDD68",
      "application_key": null,
      "address": "A4DDB314",
      "tags": [],
      "override_location": false,
      "location": null,
      "skip_fcnt_check": true,
      "rx2_data_rate": 0,
      "frame_counter": 0,
      "deduplicate": false,
      "class_c": false,
      "adr_limit": 3,
      "region": "EU868",
      "organization_id": 123,
      "organization": {
        "name": "Firefly",
        "id": 123,
        "description": null
      },
      "multicast_groups": []
    },
    {
      "updated_at": "2016-06-20T13:56:39.689000",
      "otaa": false,
      "network_session_key": "C3F4FC908AAAAFBA6A2DEA826151E7B2",
      "eui": "00000000DECF02EF",
      "name": "Device #2",
      "description": "The Device with #2",
      "inserted_at": "2016-06-20T13:56:39.689000",
      "application_session_key": "C3F4FC908AAAAFBA6A2DEA826151E7B2",
      "application_key": null,
      "address": "23DDB76A",
      "tags": [],
      "override_location": true,
      "location": {
        "lon": 9.99383518836612,
        "lat": 53.545519559434155
      },
      "skip_fcnt_check": true,
      "rx2_data_rate": 1,
      "frame_counter": 0,
      "deduplicate": false,
      "class_c": false,
      "adr_limit": null,
      "region": "EU868",
      "organization_id": 123,
      "organization": {
        "name": "Firefly",
        "id": 123,
        "description": null
      },
      "multicast_groups": [
        {
          "updated_at": "2020-04-03T12:57:42.075024",
          "region": "EU868",
          "organization_id": 123,
          "name": "testing testing",
          "mc_nwk_s_key": "FA554C6FD47D95053F6D79C1EBFDF95F",
          "mc_app_s_key": "8DA1650B4D41B44055D2AC12E4FB7FA1",
          "mc_addr": "C88CC9D7",
          "inserted_at": "2020-04-03T09:07:13.261855",
          "id": 1,
          "group_type": "c",
          "f_cnt": 165
        }
      ]
    }
  ]
}

List all devices for the organizations for which the API key is valid.

Request Fields

Field Type Description
tags Comma-separated strings Limits the devices shown to to ones supporting one or more of the tags specified, e.g. “sensor, heating” (optional)
include_organization Boolean Include the device’s organization in the response (optional, default: false)
include_multicast_groups Boolean Include the device’s multicast groups in the response (optional, default: false)

Response Format

The response is a JSON representation of an array of devices in no particular order.

Response Fields (per Device)

Field Type Description
address String Hexadecimal address of the Device
adr_limit Integer Limit ADR to this data rate
application_key String Application key valid for this device
application_session_key String Application session key valid for this device (optional)
class_c Boolean Device is a class c device
deduplicate Boolean Merge consecutive packets with equal frame counter
description String Description of the device
device_class_id Integer ID of device class if set
eui String Unique EUI for this device
frame_counter Integer Downlink frame counter
inserted_at Date Creation date of this Device
location Object {lon, lat} location coordinates if set through location override
name String Name of this device
network_session_key String Network session key valid for this device
organization Object {id, name, description} of the device’s organization (optional)
organization_id Integer Organization ID of this device
otaa Boolean Device activation is OTAA (Over the Air Activation)
override_location Boolean If location override is set for this device
region String LoRaWAN region identifier (e.g. “EU868”)
rx2_data_rate Integer Data rate used to send down packets in RX2 window
skip_fcnt_check Boolean Skip frame counter incrementing check
tags Array of strings All tags associated with this device
updated_at Date Date of last modification of this Device
multicast_groups Array of objects List of currently associated multicast groups

Show Device

Show a single device identified by either an EUI or a device address.

Show by EUI

Sample request: Show device by its EUI

  GET "https://api.fireflyiot.com/api/v1/devices/eui/D4022191A445D748?auth=secretapikey"

Every device is assigned a unique EUI when it is created. Using this value to access the device will allow correct access independent of the internal structure of the database the device data is stored in.

Show by Device Address

Sample request: Show device by its device address

  GET "https://api.fireflyiot.com/api/v1/devices/address/B43320AD?auth=secretapikey"

A device can be assigned a device address when it’s activated. Using this value to access the device will allow correct access only when the device was already issued a device address.

Response Format

Sample response

{
  "device": {
    "updated_at": "2016-06-13T10:23:44",
    "otaa": true,
    "network_session_key": "16FF5B814953444C60713918EDDFA4E7",
    "eui": "D4022191A445D748",
    "name": "A sample Device",
    "description": null,
    "inserted_at": "2016-05-13T14:11:04.816000",
    "application_session_key": "7B44352BFFAA2A784A744E61EE31BAF3",
    "application_key": "DE22FC9088517FBA6A2DED836151E722",
    "address": "B43320AD",
    "tags": [],
    "skip_fcnt_check": true,
    "rx2_data_rate": 1,
    "frame_counter": 0,
    "deduplicate": false,
    "class_c": false,
    "adr_limit": null,
    "region": "EU868",
    "organization_id": 500,
    "organization": {
      "name": "Firefly",
      "id": 500,
      "description": null
    },
    "override_location": false,
    "location": null,
    "multicast_groups": [
      {
        "updated_at": "2020-04-03T12:57:42.075024",
        "region": "EU868",
        "organization_id": 123,
        "name": "testing testing",
        "mc_nwk_s_key": "FA554C6FD47D95053F6D79C1EBFDF95F",
        "mc_app_s_key": "8DA1650B4D41B44055D2AC12E4FB7FA1",
        "mc_addr": "C88CC9D7",
        "inserted_at": "2020-04-03T09:07:13.261855",
        "id": 1,
        "group_type": "c",
        "f_cnt": 165
      }
    ]
  }
}

The response is a single JSON representation of a device, wrapped in a device object.

Response Fields

Field Type Description
address String Hexadecimal address of the Device
adr_limit Integer Limit ADR to this data rate
application_key String Application key valid for this device
application_session_key String Application session key valid for this device (optional)
class_c Boolean Device is a class c device
deduplicate Boolean Merge consecutive packets with equal frame counter
description String Description of the device
device_class_id Integer ID of device class if set
eui String Unique EUI for this device
frame_counter Integer Downlink frame counter
inserted_at Date Creation date of this Device
location Object {lon, lat} location coordinates if set through location override
name String Name of this device
network_session_key String Network session key valid for this device
organization Object {id, name, description} of the device’s organization (optional)
organization_id Integer Organization ID of this device
otaa Boolean Device activation is OTAA (Over the Air Activation)
override_location Boolean If location override is set for this device
region String LoRaWAN region identifier (e.g. “EU868”)
rx2_data_rate Integer Data rate used to send down packets in RX2 window
skip_fcnt_check Boolean Skip frame counter incrementing check
tags Array of strings All tags associated with this device
updated_at Date Date of last modification of this Device
multicast_groups Array of objects List of currently associated multicast groups

Create Device

Sample request

POST "https://api.fireflyiot.com/api/v1/devices?auth=secretapikey"

Sample request body

{
  "organization": 11,
  "device": {
    "name": "Device #3",
    "description": "this is the third device",
    "tags": ["tag1", "tag2"],
    "otaa": false,
    "eui": "800086E8F84D1C6A",
    "address": "AB6A392E",
    "network_session_key": "E66E964F8C3A1A14DE729BF95DA53E52",
    "application_session_key": "E95A58B86883E3BADDEE15E7DC24442F",
    "class_c": false,
    "region": "EU868",
    "rx2_data_rate": 0,
    "adr_limit": 2,
    "deduplicate": false,
    "skip_fcnt_check": true,
    "device_class_id": 1,
    "override_location": true,
    "location": {"lat": 53.4, "lon": 9.9}
  }
}

Sample response

{
  "device": {
    "id": 53,
    "name": "Device #3",
    "description": "this is the third device",
    "tags": [
      "tag1",
      "tag2"
    ],
    "otaa": false,
    "eui": "800086E8F84D1C6A",
    "address": "AB6A392E",
    "application_key": null,
    "network_session_key": "E66E964F8C3A1A14DE729BF95DA53E52",
    "application_session_key": "E95A58B86883E3BADDEE15E7DC24442F",
    "class_c": false,
    "region": "EU868",
    "rx2_data_rate": 0,
    "adr_limit": 2,
    "deduplicate": false,
    "skip_fcnt_check": true,
    "device_class_id": 1,
    "override_location": true,
    "location": {
      "lat": 53.4,
      "lon": 9.9
    },
    "frame_counter": null,
    "organization_id": 11,
    "inserted_at": "2020-08-07T08:47:42.025744",
    "updated_at": "2020-08-07T08:47:42.025757"
  }
}

Request Fields

Field Type Description
organization Integer ID of the organization (required)
application Integer ID of the application (optional)
device Object Device parameters
device.name String Name (optional)
device.description String Description (optional)
device.tags Array of strings Tags (optional)
device.otaa Boolean Device activation is OTAA (true) or ABP (false) (required)
device.eui String Hex-encoded EUI (required)
device.application_key String Hex-encoded application key (required if OTAA)
device.address String Hex-encoded device address (required if ABP)
device.network_session_key String Hex-encoded network session key (required if ABP)
device.application_session_key String Hex-encoded application session key (optional if ABP, ignored if OTAA)
device.class_c Boolean Class C capable (optional, default: false)
device.region String LoRaWAN region identifier (optional, default: “EU868”)
device.rx2_data_rate Integer Data rate used to send down packets in RX2 window (optional)
device.adr_limit Integer Limit ADR to this data rate (optional)
device.deduplicate Boolean Merge consecutive packets with equal frame counter (optional, default: false)
skip_fcnt_check Boolean Skip frame counter incrementing check (optional, default: true)
device.device_class_id Integer ID of device class (optional)
device.override_location Boolean Override location provided by device class (optional, default: false)
device.location Object {lon, lat} location coordinates if set through location override (optional)

Response Fields

Same as Single Device Response fields.

Update Device

Sample request

PUT "https://api.fireflyiot.com/api/v1/devices/eui/2564927382738492?auth=secretapikey"

Sample request body

{
  "device": {
    "description": "A new test device"
  }
}

Sample response

{
  "device": {
    "updated_at": "2020-08-07T11:26:12.391522",
    "tags": [],
    "skip_fcnt_check": true,
    "rx2_data_rate": null,
    "region": "EU868",
    "override_location": false,
    "otaa": true,
    "organization_id": 11,
    "network_session_key": null,
    "name": null,
    "location": null,
    "inserted_at": "2020-08-07T09:14:33.707253",
    "id": 55,
    "frame_counter": 0,
    "eui": "2564927382738492",
    "device_class_id": null,
    "description": "A new test device",
    "deduplicate": false,
    "class_c": false,
    "application_session_key": null,
    "application_key": "0FD295473FF2EC81FAA2447C70C8732F",
    "adr_limit": null,
    "address": null
  }
}

A device can be updated by sending a PUT/PATCH request to the corresponding endpoint. It expects a JSON-body with the fields that should be changed.

This endpoint will not send packets, it will only reconfigure the device. To send packets, use the Send Packets to Device method.

Request Fields

Only the fields that should be updated need to be specified.

Field Type Description
device Object Device parameters
device.name String Name (optional)
device.description String Description (optional)
device.tags Array of strings Tags (optional)
device.otaa Boolean Device activation is OTAA (true) or ABP (false) (required)
device.eui String Hex-encoded EUI (required)
device.application_key String Hex-encoded application key (required if OTAA)
device.address String Hex-encoded device address (required if ABP)
device.network_session_key String Hex-encoded network session key (required if ABP)
device.application_session_key String Hex-encoded application session key (optional if ABP, ignored if OTAA)
device.class_c Boolean Class C capable (optional, default: false)
device.region String LoRaWAN region identifier (optional, default: “EU868”)
device.rx2_data_rate Integer Data rate used to send down packets in RX2 window (optional)
device.adr_limit Integer Limit ADR to this data rate (optional)
device.deduplicate Boolean Merge consecutive packets with equal frame counter (optional, default: false)
skip_fcnt_check Boolean Skip frame counter incrementing check (optional, default: true)
device.device_class_id Integer ID of device class (optional)
device.override_location Boolean Override location provided by device class (optional, default: false)
device.location Object {lon, lat} location coordinates if set through location override (optional)

Response Fields

Same as Single Device Response fields.

Delete Device

Sample request

DELETE "https://api.fireflyiot.com/api/v1/devices/eui/2564927382738492?auth=secretapikey"

Sample response

204 No Content

To delete a device, a DELETE request must be sent with the corresponding device EUI.

Response

When the device was deleted, a 204 success message will be returned.

List Packets

Sample request

GET "https://api.fireflyiot.com/api/v1/devices/eui/2564927382738492/packets?auth=secretapikey"

Sample response

{
  "more": true,
  "packets": [
    {
      "ack": false,
      "bandwidth": 125,
      "codr": "4/6",
      "device_eui": "2564927382738492",
      "fopts": "",
      "fcnt": 12882,
      "freq": 866.349812,
      "gwrx": [
          {
            "tmst": 3977700196,
            "time": "2016-06-22T07:35:34.774224Z",
            "rssi": 2,
            "lsnr": 8.5,
            "gweui": "0000024B080E006D"
          }
        ],
      "modu": "LORA",
      "mtype": "unconfirmed_data_up",
      "payload_encrypted": false,
      "payload": "415141414277673D",
      "port": 2,
      "received_at": "2016-06-22T09:35:35",
      "size": 28,
      "spreading_factor": 7,
      "uid": "8a569133-ba44-4d7e-5555-af62faf9f722"
    },
    {
      "ack": true,
      "bandwidth": 100,
      "codr": "4/6",
      "device_eui": "2564927382738492",
      "fopts": "",
      "fcnt": 12883,
      "freq": 866.347719,
      "gwrx": [
          {
            "tmst": 1468815219,
            "time": "2016-07-18T04:13:39.573216Z",
            "rssi": -35,
            "lsnr": 5.1,
            "gweui": "0102030205060708"
          }
        ],
      "modu": "LORA",
      "mtype": "confirmed_data_up",
      "payload_encrypted": false,
      "payload": "415141414277673A",
      "port": 2,
      "received_at": "2016-06-22T09:39:16",
      "size": 28,
      "spreading_factor": 7,
      "uid": "8a569133-7752-4d7e-810d-af62faf9f722"
    }
  ]
}

Returns packets received by the device.

Request Query Parameters

Query Parameter Description
direction When set to asc, it will return the oldest packets first. When set to desc, it will return the most recent packets. (optional, default: desc).
limit_to_last Number of packets to be returned. Ordered by creation date, descending (unless otherwise specified through the direction parameter). (optional, default: 1, max: 100)
offset Number of most recent packets to skip before returning packets. (optional, default: 0)
payload_only Only return payload, parsed payload (where applicable), timestamp, and device address of the packet. (optional, default: false)
received_after Only return packets after this date. If this parameter is used and no limit_to_last value is supplied, limit_to_last will be set to 10. Default is the Unix epoch timestamp (meaning that no packets will be omitted). Specify an ISO 8601 date string here.

Response

The more field will return a boolean value stating if there are more packets in the database than collected with the query specified. This should be used for proper paging implementations.

In the packets collection that is returned, every item represents a packet that was sent by the device.

As a reference, please check the LoRa documentation for the precise meaning of this data.

Field Description
ack Acknowledgement
bandwidth Bandwidth
codr LoRa ECC coding rate identifier
datr Data rate
device_eui Device EUI
fopts FOpts
fcnt Frame counter
freq Frequency
gwrx Data relevant to the gateway that received the packet
gwrx.gweui Gateway EUI
gwrx.lsnr LSNR
gwrx.rssi RSSI
gwrx.tmst Gateway-specific timestamp of when the packet was received (nanoseconds). This is not a ‘real’ time value, as it is reset whenever the gateway is restarted or instructed to reset. Used to guarantee uniqueness of packets.
gwrx.time ISO 8601 timestamp of when the packet was received
modu Modulation, will be “LORA”
mtype Type and direction of Packet
parsed If available, the decoded and parsed payload (as configured in the device class)
payload Payload that was sent in the packet
payload_encrypted Was the payload encrypted?
port Port on which the packet was sent
received_at ISO 8601 timestamp of server receiption
size Length of the payload
spreading_factor Spreading factor
uid Unique ID of the packet used by the server

Track the uid field to ensure packet uniqueness when persisting it into a database.

List Mac Events

Sample request

GET "https://api.fireflyiot.com/api/v1/devices/eui/2564927382738492/mac_events?auth=secretapikey"

Sample response


{
  "more": true,
  "mac_events": [
    {
      "uid": "8a569133-aa44-4d7e-810d-af62faf9f722",
      "type": "join_accept",
      "received_at": "2016-07-15T14:31:11",
      "frame_counter": null,
      "for_frame_counter": null,
      "direction": "down",
      "device_eui": "2564927382738492"
    },
    {
      "uid": "2d4289f0-03c9-4c42-b078-04aff6e91180",
      "type": "join_request",
      "received_at": "2016-07-15T14:31:11",
      "frame_counter": null,
      "for_frame_counter": null,
      "direction": "up",
      "device_eui": "2564927382738492"
    }
  ]
}

Returns non-data packets (e.g. join requests, join accepts) received by and sent to the device.

Request Query Parameters

Query Parameter Description
direction When set to asc, it will return the oldest packets first. When set to desc, it will return the most recent packets. (optional, default: desc).
limit_to_last Number of packets to be returned. Ordered by creation date, descending (unless otherwise specified through the direction parameter). (optional, default: 1, max: 100)
offset Number of most recent packets to skip before returning packets. (optional, default: 0)
received_after Only return packets after this date. If this parameter is used and no limit_to_last value is supplied, limit_to_last will be set to 10. Default is the Unix epoch timestamp (meaning that no packets will be omitted). Specify an ISO 8601 date string here.

Response

The more field will return a boolean value stating of there are more mac events in the database than collected with the query specified. This should be used for proper paging implementations.

In the mac_events collection that is returned, every item represents a mac event that was sent to or received by the device.

As a reference, please check the LoRa documentation for the precise meaning of this data.

Field Description
device_eui Device EUI
frame_counter Frame counter
for_frame_counter Frame counter reference
received_at ISO 8601 timestamp of server receiption
direction Direction of the packet, up (from the device) or down (to the device)
type Type of the packet, can be any of the following: join_request, join_accept, ack_up, ack_down, mic_fail, appserver_join_accept.
uid Unique ID of the packet used by the server

Track the uid field to ensure mac event uniqueness when persisting it into a database.

List Down Packets

Sample request

GET "https://api.fireflyiot.com/api/v1/devices/eui/2564927382738492/down_packets?auth=secretapikey"

Sample response


{
  "packets": [
    {
      "spreading_factor": 12,
      "sent": "2016-08-30T10:20:35.139026",
      "rx_data": {
        "tmst": 3014015996,
        "time_on_air": 1155072,
        "size": 12,
        "rx_window": "rx1",
        "rfch": 0,
        "powe": 14,
        "modu": "LORA",
        "ipol": true,
        "gw_mac": "0000024B080E00A1",
        "freq": 868.5,
        "datr": "SF12BW125",
        "data": "YCOfO0EgFBKtaGMw",
        "codr": "4/5"
      },
      "raw_payload": "60239F3B41444412AD686330",
      "port": 0,
      "payload": "",
      "parsed_packet": {
        "port": 0,
        "pending": false,
        "payload": null,
        "mtype": "unconfirmed_data_down",
        "mic_pass": true,
        "major": 0,
        "mac_cmds": [],
        "fopts_len": 0,
        "fcnt": 4628,
        "dir": "down",
        "dev_eui": null,
        "dev_addr_hex": "223b9f23",
        "adrackreq": false,
        "adr": false,
        "ack": true
      },
      "inserted_at": "2016-08-30T12:20:35",
      "frame_counter": 4628,
      "device_eui": "2564927382738492",
      "bandwidth": 125,
      "ack": false,
      "uid": "8a569133-aa44-4d7e-810d-af62faf9f722"
    }
  ],
  "more": true
}

Returns packets sent to the device.

Request Query Parameters

Query Parameter Description
direction When set to asc, it will return the oldest packets first. When set to desc, it will return the most recent packets. (optional, default: desc).
limit_to_last Number of packets to be returned. Ordered by creation date, descending (unless otherwise specified through the direction parameter). (optional, default: 1, max: 100)
offset Number of most recent packets to skip before returning packets. (optional, default: 0)
payload_only Only return payload, parsed payload (where applicable), timestamp, and device address of the packet. (optional, default: false)
received_after Only return packets after this date. If this parameter is used and no limit_to_last value is supplied, limit_to_last will be set to 10. Default is the Unix epoch timestamp (meaning that no packets will be omitted). Specify an ISO 8601 date string here.

Response

The more field will return a boolean value stating of there are more down packets in the database than collected with the query specified. This should be used for proper paging implementations.

In the packets collection that is returned, every item represents a down packet that was sent to the device.

As a reference, please check the LoRa documentation for the precise meaning of this data.

Field Description
ack Acknowledgement
bandwidth Bandwidth
device_eui Device EUI
frame_counter Frame counter
parsed_packet The decoded and parsed payload of the packet
payload Payload
received_at ISO 8601 timestamp of server receiption
rx_data Meta data relevant to the gateway
sent ISO 8601 timestamp of sent date (null if not sent yet)
spreading_factor Spreading factor
uid Unique ID of the packet used by the server

Track the uid field to ensure packet uniqueness when persisting it into a database.

Create (send) packet to device

Sample request

POST "https://api.fireflyiot.com/api/v1/devices/eui/2564927382738492/packet?auth=secretapikey"

Sample request body

{
  "payload": "Test Payload",
  "encoding": "utf8",
  "port": 1,
  "confirmed": false
}

Sample response

{
  "sent_packet": {
    "uid": "724f0f4b-df8c-4e5b-a00d-203bdfa737ab",
    "port": 1,
    "payload": "54657374205061796C6F6164",
    "fcnt": 15
  }
}

Send a packet to the device. Make sure the payload is correctly encoded as specified on the encoding parameter.

Request Fields

The request body must be a valid JSON object with these fields:

Field Type Description
encoding String Encoding of the payload. Allowed values are base16, base64 and utf8
payload String Payload to be sent in the device
port Integer Port on the device to send the packet to
confirmed Boolean Ask the device to acknowledge the down packet (optional, default: false)
gateway_id String For class C devices a gateway EUI can be specified that will be used to send the down packet (optional)

Response Fields

Field Description
fcnt Integer
payload String
port Integer
uid String

Show Down Packet

Sample request

GET "https://api.fireflyiot.com/api/v1/devices/eui/2564927382738492/down_packets/724f0f4b-df8c-4e5b-a00d-203bdfa737ab?auth=secretapikey"

Sample response


{
  "packet": {
    "uid": "724f0f4b-df8c-4e5b-a00d-203bdfa737ab",
    "spreading_factor": null,
    "sent": null,
    "rx_data": null,
    "received_at": "2020-04-08T09:11:19.055259",
    "raw_payload": null,
    "port": 12,
    "payload": "ABCD",
    "parsed_packet": null,
    "frame_counter": 1,
    "device_eui": "2564927382738492",
    "bandwidth": null,
    "ack": false
  }
}

Returns a single packet that was sent or is to be sent to the device, identified by its uid. If the response field sent is null, then the down packet is still queued and has not been sent yet.

Response

Same as List Down Packets.

Remove Queued Down Packet

Sample request

DELETE "https://api.fireflyiot.com/api/v1/devices/eui/2564927382738492/down_packets/724f0f4b-df8c-4e5b-a00d-203bdfa737ab?auth=secretapikey"

Sample response

204 No Content

To remove a queued down packet, a DELETE request must be sent with the corresponding uid. Only packets that have not been sent yet ("sent": null) can be deleted.

Response

When the packet was deleted, a 204 success message will be returned.

Manage Multicast Groups

Sample request

POST "https://api.fireflyiot.com/api/v1/devices/eui/2564927382738492/multicast_groups?auth=secretapikey"

Sample request body

{
  "multicast_groups": [1]
}

Sample response

{
  "device": {
    "updated_at": "2016-06-13T10:23:44",
    "otaa": true,
    "network_session_key": "16FF5B814953444C60713918EDDFA4E7",
    "eui": "2564927382738492",
    "name": "A sample Device",
    "description": null,
    "inserted_at": "2016-05-13T14:11:04.816000",
    "application_session_key": "7B44352BFFAA2A784A744E61EE31BAF3",
    "application_key": "DE22FC9088517FBA6A2DED836151E722",
    "address": "B43320AD",
    "tags": [],
    "organization_id": 500,
    "organization": {
      "name": "Firefly",
      "id": 500,
      "description": null
    },
    "override_location": false,
    "location": null,
    "multicast_groups": [
      {
        "updated_at": "2020-04-03T12:57:42.075024",
        "region": "EU868",
        "organization_id": 123,
        "name": "testing testing",
        "mc_nwk_s_key": "FA554C6FD47D95053F6D79C1EBFDF95F",
        "mc_app_s_key": "8DA1650B4D41B44055D2AC12E4FB7FA1",
        "mc_addr": "C88CC9D7",
        "inserted_at": "2020-04-03T09:07:13.261855",
        "id": 1,
        "group_type": "c",
        "f_cnt": 165
      }
    ]
  }
}

Associate a device to multicast groups or remove associations. The multicast_groups field is not additive, it must always consist of the entire list of multicast groups that should be associated to this device after the request is done. Set to empty list to remove all multicast group associations.

Request Fields

The request rody must be a valid JSON object with these fields:

Field Type Description
multicast_groups Array of Integer List of multicast group IDs

Response Fields

Same as Show Device.

Applications

Show Applications

Sample request

GET "https://api.fireflyiot.com/api/v1/applications?auth=secretapikey"

Sample response

{
  "applications": [
    {
      "updated_at": "2016-05-31T14:04:47.598000",
      "name": "Testing Applications",
      "inserted_at": "2016-05-31T14:04:47.598000",
      "id": 18,
      "eui": null,
      "description": "Test Application 1"
    },
    {
      "updated_at": "2016-06-07T15:02:41.613000",
      "name": "App Test 1",
      "inserted_at": "2016-06-07T15:02:41.613000",
      "id": 19,
      "eui": null,
      "description": "E.ON power meter application"
    },
    {
      "updated_at": "2016-04-21T10:47:21.770000",
      "name": "Test Applikation 2",
      "inserted_at": "2016-04-21T10:47:21.770000",
      "id": 3,
      "eui": "3435343334353435",
      "description": "Beschreibung für die Applikation"
    }
  ]
}

List all applications for the organizations for which the API key is valid.

Response Format

The response is a JSON representation of an array of applications in no particular order.

Response Fields (per Device)

Field Type Description
inserted_at Date Date of creation of this application
description String Description of this application
eui String Unique EUI of this application
id Integer Unique ID of this application in the Firefly database
name String Name for this application
sink JSON Additional data for the application
updated_at Date Date of last modification of this application

List EUIs of Devices

Sample request

GET "https://api.fireflyiot.com/api/v1/applications/1/euis?auth=secretapikey"

Sample response

{
  "devices": [
    {
      "eui": "000000004136AF4A",
      "address": "4136AF4A"
    },
    {
      "eui": "00000000232317D2",
      "address": "232317D2"
    },
    {
      "eui": "000000004137DF3A",
      "address": "4137DF3A"
    }
  ]
}

Lists all devices that belong to this application.

Response Format

The response is a JSON representation of an array of devices in no particular order.

Response Fields (per Device)

Field Type Description
address String Hexadecimal representation of the device address
eui String Device EUI

Device Classes

Show Device Classes

Sample request

GET "https://api.fireflyiot.com/api/v1/device_classes?auth=secretapikey"

Sample response

{
  "device_classes": [
    {
      "updated_at": "2016-04-22T12:52:16.109000",
      "script": {
        "variables": {
          "gps": {
            "type": "gps",
            "name": "gps"
          },
          "batteryLevel": {
            "type": "range",
            "name": "batteryLevel"
          },
          "battery": {
            "type": "hidden",
            "name": "battery"
          }
        },
        "parseElements": [
          {
            "type": "int",
            "target": "battery",
            "bits": "8"
          },
          {
            "type": "int",
            "target": "gps.latitude",
            "signed": true,
            "bits": "24"
          },
          {
            "type": "int",
            "target": "gps.longitude",
            "signed": true,
            "bits": "24"
          },
          {
            "type": "int",
            "target": "gps.altitude",
            "signed": true,
            "bits": "16"
          }
        ],
        "calculateElements": [
          {
            "target": "batteryLevel",
            "formula": "battery != 0 ? (battery - 1) / 253 : null"
          },
          {
            "target": "gps.latitude",
            "formula": "gps.latitude / (1 << 23) * 90"
          },
          {
            "target": "gps.longitude",
            "formula": "gps.longitude / (1 << 23) * 180"
          }
        ]
      },
      "name": "Test Device Class",
      "inserted_at": "2016-04-20T15:09:18.911000",
      "id": 2,
      "description": null
    }
  ]
}

This route shows all device classes registered to the API key.

Response Format

The response is a JSON representation of an array of device classes in no particular order.

Response Fields (per Device Class)

Field Type Description
description String Description
id Integer ID
inserted_at String Date of Creation
name String Name
script JSON Script data for the frontend application
updated_at String Date of last modification

Show Single Device Class

Sample request

GET "https://api.fireflyiot.com/api/v1/device_classes/1?auth=secretapikey"

Sample response

{
  "device_classes": {
    "updated_at": "2016-04-22T12:52:16.109000",
    "script": {
      "variables": {
        "gps": {
          "type": "gps",
          "name": "gps"
        },
        "battery": {
          "type": "hidden",
          "name": "battery"
        }
      },
      "parseElements": [
        {
          "type": "int",
          "target": "battery",
          "bits": "8"
        },
        {
          "type": "int",
          "target": "gps.latitude",
          "signed": true,
          "bits": "24"
        },
        {
          "type": "int",
          "target": "gps.longitude",
          "signed": true,
          "bits": "24"
        },
        {
          "type": "int",
          "target": "gps.altitude",
          "signed": true,
          "bits": "16"
        }
      ],
      "calculateElements": [
        {
          "target": "batteryLevel",
          "formula": "battery != 0 ? (battery - 1) / 253 : null"
        },
        {
          "target": "gps.latitude",
          "formula": "gps.latitude / (1 << 23) * 90"
        },
        {
          "target": "gps.longitude",
          "formula": "gps.longitude / (1 << 23) * 180"
        }
      ]
    },
    "name": "Test Device Class",
    "inserted_at": "2016-04-20T15:09:18.911000",
    "id": 2,
    "description": null
  }
}

This route shows a single device class registered to the API key by ID.

Response Fields

Field Type Description
description String Description
id Integer ID
inserted_at String Date of Creation
name String Name
script JSON Script data for the frontend application
updated_at String Date of last modification

List EUIs of Devices

Sample request

GET "https://api.fireflyiot.com/api/v1/device_classes/1/euis?auth=secretapikey"

Sample response

{
  "devices": [
    {
      "eui": "000000004136AF4A",
      "address": "4136AF4A"
    },
    {
      "eui": "00000000232317D2",
      "address": "232317D2"
    },
    {
      "eui": "000000004137DF3A",
      "address": "4137DF3A"
    }
  ]
}

Lists all devices that belong to this device class.

Response Format

The response is a JSON representation of an array of devices in no particular order.

Response Fields (per Device)

Field Type Description
address String Hexadecimal representation of the device address
eui String Device EUI

All Packets

Sample request

GET "https://api.fireflyiot.com/api/v1/packets?auth=secretapikey"

The API provides an endpoint to fetch all packets for the organizations for which your API key was issued.

Request Query Parameters

Query Parameter Description
direction When set to asc, it will return the oldest packets first. When set to desc, it will return the most recent packets. (optional, default: desc).
limit_to_last Number of packets to be returned. Ordered by creation date, descending (unless otherwise specified through the direction parameter). (optional, default: 1, max: 100)
offset Number of most recent packets to skip before returning packets. (optional, default: 0)
payload_only Only return payload, parsed payload (where applicable), timestamp, and device address of the packet. (optional, default: false)
received_after Only return packets after this date. If this parameter is used and no limit_to_last value is supplied, limit_to_last will be set to 10. Default is the Unix epoch timestamp (meaning that no packets will be omitted). Specify an ISO 8601 date string here.
skip_suborgs Do NOT show packets from devices that are not directly in the organization that the API key is registered for. (optional)

Response

The API will provide the same fields as in List Packets.

Multicast Groups

Multicast group object

Example multicast group object

{
  "id": 1,
  "name": "test name",
  "mc_addr": "F4F41991",
  "mc_nwk_s_key": "86D893F1E98058D528A2E4C857290758",
  "mc_app_s_key": "01CB10490014E6BFCE384CD22B32B3EE",
  "region": "EU868",
  "group_type": "c",
  "f_cnt": 0,
  "organization_id": 123,
  "inserted_at": "2020-03-17T15:51:44.707076",
  "updated_at": "2020-03-17T15:54:38.479367"
}
Field Type Description
id Integer (read-only) ID of the multicast group
name String Name (required)
mc_addr String Hex-encoded multicast group address (required, length: 8 characters)
mc_nwk_s_key String Hex-encoded multicast group network session key (required, length: 32 characters)
mc_app_s_key String Hex-encoded multicast group application session key (required, length: 32 characters)
region String Region identifier (default: “EU868”)
group_type String Group type/class (default: “c”)
f_cnt Integer Frame counter (default: 0)
organization_id Integer Organization ID (required)

Create multicast group

Endpoint POST /api/v1/multicast_groups?auth={secretapikey}

Request Body JSON object with a field multicast_group that contains a multicast group object, the id field is generated automatically

Show multicast group

Endpoint GET /api/v1/multicast_groups/{id}?auth={secretapikey}

List all multicast groups

Endpoint GET /api/v1/multicast_groups?auth={secretapikey}

Update multicast group

Endpoint PUT /api/v1/multicast_groups/{id}?auth={secretapikey}

Request Body JSON object with field multicast_group that contains all the values you want to overwrite. See: multicast group object

Delete multicast group

Endpoint DELETE /api/v1/multicast_groups/{id}?auth={secretapikey}

List all associated devices

Endpoint GET /api/v1/multicast_groups/{id}/devices?auth={secretapikey}

Multicast down packet object

{
  "updated_at": "2020-04-03T12:57:42.077389",
  "uid": "0854c37d-fd25-4e0c-bd4f-ff3e7855908c",
  "spreading_factor": 12,
  "sent": "2020-04-03T12:57:42.077319",
  "rx_data": {
    "time_on_air": 1482752,
    "size": 23,
    "rx_window": "rx2",
    "rfch": 0,
    "powe": 27,
    "modu": "LORA",
    "ipol": true,
    "imme": true,
    "gwtx": [
      {
        "sent": "2020-04-03T12:57:42.077319Z",
        "gweui": "7276FF0000000000"
      }
    ],
    "freq": 869.525,
    "datr": "SF12BW125",
    "data": "YKrP7ikApQAB0dnWXVrobDA6o5BJch4=",
    "codr": "4/5"
  },
  "raw_payload": "60AACFEE2900A50001D1D9D65D5AE86C303AA39049721E",
  "port": 1,
  "payload": "30000000010000003005",
  "parsed_packet": {},
  "organization_id": 123,
  "multicast_group_id": 1,
  "inserted_at": "2020-04-03T12:57:41.673260",
  "frame_counter": 165,
  "bandwidth": 125
}

The multicast down packet object is similar to the regular device down packet with some notable differences:

Field Description
uid Unique ID of the multicast down packet
sent Timestamp when sent, null when queued
multicast_group_id ID of the multicast group
rx_data.gwtx List of transmit objects for each gateway used to broadcast the down packet

Create (send) multicast down packet

Endpoint POST /api/v1/multicast_groups/{id}/multicast_down_packets?auth={secretapikey}

Sample request body

{
  "payload": "ABCDEF",
  "encoding": "base16",
  "port": 1
}

Send a downlink packet to the multicast group. Make sure the payload is correctly encoded as specified on the encoding parameter.

Request Fields

The Request Body must be a valid JSON Object with these fields:

Field Type Description
encoding String Encoding of the payload. Allowed values are base16, base64 and utf8 (required)
payload String Payload to be sent in the packet (required)
port Integer Port to send the packet to (required)
gateway_ids Array of String List of gateway IDs to use for sending (optional)

Response

If successful a multicast down packet object with automatically generated uid.

List all multicast down packets for a multicast group

Endpoint GET /api/v1/multicast_groups/{id}/multicast_down_packets?auth={secretapikey}

Same query parameters as in list down packets apply.

Show multicast down packet

Endpoint GET /api/v1/multicast_groups/{id}/multicast_down_packets/{uid}?auth={secretapikey}

Delete queued multicast down packet

Endpoint DELETE /api/v1/multicast_groups/{id}/multicast_down_packets/{uid}?auth={secretapikey}

Only packets that have not been sent yet ("sent": null) can be deleted.

Gateways

Gateway object

Example gateway object

{
  "id": 1,
  "name": "test name",
  "eui": "C859D9EED5333DE6",
  "auth_token": "6B1A3106D0B93E63F85E143B68333B0D",
  "organization_id": 123,
  "inserted_at": "2020-03-17T15:51:44.707076",
  "updated_at": "2020-03-17T15:54:38.479367"
}
Field Type Description
id Integer (read-only) ID of the gateway
name String Name (required)
eui String Hex-encoded gateway EUI (required, length: 16 characters)
auth_token String Hex-encoded gateway auth token used for Basic Station client token auth mode (length: 32 characters)
organization_id Integer Organization ID (required)

Create gateway

Endpoint POST /api/v1/gateways?auth={secretapikey}

Request Body JSON object with a field gateway that contains a gateway object, the id field is generated automatically

Show gateway

Endpoint GET /api/v1/gateways/{id}?auth={secretapikey}

List all gateways

Endpoint GET /api/v1/gateways?auth={secretapikey}

Update gateway

Endpoint PUT /api/v1/gateways/{id}?auth={secretapikey}

Request Body JSON object with field gateway that contains all the values you want to update. See: gateway object

Delete gateway

Endpoint DELETE /api/v1/gateways/{id}?auth={secretapikey}

API Key Management

Show own API Key Metadata

Sample request

GET "https://api.fireflyiot.com/api/v1/apikeys?auth=secretapikey"

Sample response

{
  "apikey": {
    "valid_until": "2017-02-20T14:28:00",
    "rate_scale": 1000,
    "rate_limit": 5,
    "organization_id": 25,
    "name": "Test API Key",
    "may_be_modified": false,
    "key": "93444e69bd7aadddd0b280dcc20e479b",
    "created_at": "2016-11-22T14:28:11.000000"
  }
}

Shows information about validity and rate limiting values attached to the API key being used.

Response Format

The response is a JSON representation of an API key.

Response Fields

Field Type Description
valid_until Date ISO date of the point in time when this API key becomes automatically revoked
rate_scale Integer Time window for rate limiting
rate_limit Integer Number of allowed calls in rate limit time window
organization_id Integer ID of the organization for which the API key was issued
name String Name
may_be_modified Boolean States whether this API key can be changed by the organization it was issued for
key String The actual value of the API key, to be used as a credential
created_at Date Date of when the API key was created

Show API Key Metadata

Sample request

GET "https://api.fireflyiot.com/api/v1/apikeys/93444e69bd7aadddd0b280dcc20e479b?auth=secretapikey"

Sample response

{
  "apikey": {
    "valid_until": "2017-02-20T14:28:00",
    "rate_scale": 1000,
    "rate_limit": 5,
    "organization_id": 25,
    "name": "Test API Key",
    "may_be_modified": false,
    "key": "93444e69bd7aadddd0b280dcc20e479b",
    "created_at": "2016-11-22T14:28:11.000000"
  }
}

Shows information about validity and rate limiting values attached to the API key sent as a query parameter.

Response Format

The response is a JSON representation of an API key.

Response Fields

Field Type Description
valid_until Date ISO date of the point in time when this API key becomes automatically revoked
rate_scale Integer Time window for rate limiting
rate_limit Integer Number of allowed calls in rate limit time window
organization_id Integer ID of the organization for which the API key was issued
name String Name
may_be_modified Boolean States whether this API key can be changed by the organization it was issued for
key String The actual value of the API key, to be used as a credential
created_at Date Date of when the API key was created

Show API Keys for Own Organization

Sample request

GET "https://api.fireflyiot.com/api/v1/apikeys/organization?auth=secretapikey"

Sample response

{
  "remaining": 3,
  "apikeys": [
    {
      "valid_until": "2016-11-17T12:19:00",
      "rate_scale": 10000,
      "rate_limit": 100,
      "organization_id": 25,
      "name": "Csaba Harta",
      "may_be_modified": false,
      "key": "9b608eaba123456c51dc25eb438d54c3",
      "created_at": "2016-08-19T12:19:47.000000"
    },
    {
      "valid_until": "2017-02-13T16:01:55.192672",
      "rate_scale": 10000,
      "rate_limit": 50,
      "organization_id": 25,
      "name": "Test HCP Rate 50",
      "may_be_modified": false,
      "key": "fe65af387dceeb5543435780c48babb",
      "created_at": "2016-11-15T16:01:55.000000"
    }
  ]
}

Shows all API keys issued for the organization for which the API key used is issued.

Response Format

The response is a JSON representation of a list of API keys.

Response Fields (per API Key)

Field Type Description
valid_until Date ISO date of the point in time when this API key becomes automatically revoked
rate_scale Integer Time window for rate limiting
rate_limit Integer Number of allowed calls in rate limit time window
organization_id Integer ID of the organization for which the API key was issued
name String Name
may_be_modified Boolean States whether this API key can be changed by the organization it was issued for
key String The actual value of the API key, to be used as a credential
created_at Date Date of when the API key was created

Response Fields (additional)

Field Type Description
remaining Integer The number of API keys that can be created before the limit is reached

Show API Keys for Organization

Sample request

GET "https://api.fireflyiot.com/api/v1/apikeys/organization/25?auth=secretapikey"

Sample response

{
  "remaining": 3,
  "apikeys": [
    {
      "valid_until": "2016-11-17T12:19:00",
      "rate_scale": 10000,
      "rate_limit": 100,
      "organization_id": 25,
      "name": "Csaba Harta",
      "may_be_modified": false,
      "key": "9b608eaba123456c51dc25eb438d54c3",
      "created_at": "2016-08-19T12:19:47.000000"
    },
    {
      "valid_until": "2017-02-13T16:01:55.192672",
      "rate_scale": 10000,
      "rate_limit": 50,
      "organization_id": 25,
      "name": "Test HCP Rate 50",
      "may_be_modified": false,
      "key": "fe65af387dceeb5543435780c48babb",
      "created_at": "2016-11-15T16:01:55.000000"
    }
  ]
}

Shows all API keys issued for the specified organization.

Response Format

The response is a JSON representation of a list of API keys.

Response Fields (per API Key)

Field Type Description
valid_until Date ISO date of the point in time when this API key becomes automatically revoked
rate_scale Integer Time window for rate limiting
rate_limit Integer Number of allowed calls in rate limit time window
organization_id Integer ID of the organization for which the API key was issued
name String Name
may_be_modified Boolean States whether this API key can be changed by the organization it was issued for
key String The actual value of the API key, to be used as a credential
created_at Date Date of when the API key was created

Response Fields (additional)

Field Type Description
remaining Integer The number of API keys that can be created before the limit is reached

Renew API Key

Sample request

PUT "https://api.fireflyiot.com/api/v1/apikeys/renew?auth=secretapikey"

Sample response

{
  "revoked_key": {
    "revoked": true,
    "key": "93444e69bd7aadddd0b280dcc20e479b"
  },
  "created_key": {
    "valid_until": "2017-05-17T11:52:19.789049",
    "rate_scale": 20,
    "rate_limit": 20,
    "organization_id": -1,
    "name": "test",
    "may_be_modified": false,
    "key": "b974e02ccd082b0ddddaa7db96e44439",
    "created_at": "2017-02-16T11:52:19.825607"
  }
}

Revokes currently used API key and creates a new API Key in one atomic operation.

Response Format

The response is a JSON representation of the newly created API key and information about the revocation of the old one.

Response Fields

Field Type Description
revoked_key.revoked Boolean States whether the old API key was successfully revoked
revoked_key.key String The API key that was revoked
created_key.valid_until Date ISO Date of the point in time when the new API key becomes automatically revoked
created_key.rate_scale Integer Time window for rate limiting
created_key.rate_limit Integer Amount of allowed calls in rate limit time window
created_key.organization_id Integer Identifier of the organization for which the new API key was issued
created_key.name String Name of the new API key
created_key.may_be_modified Boolean States whether the new API key can be changed by the organization it was issued for
created_key.key String The actual value of the new API key, to be used as a credential
created_key.created_at Date Date of when the new API key was created

Revoke API Keys

Sample request

POST "https://api.fireflyiot.com/api/v1/apikeys/revoke?auth=secretapikey"
{
  keys: ["3c5e3b7a4c7f746a7043896bf4bd5643", "d1d0c10c3196e811999cd7535f08bd16"]
}

Sample response

{
  "apikeys": [
    {
      "revoked": true,
      "key": "3c5e3b7a4c7f746a7043896bf4bd5643"
    },
    {
      "revoked": true,
      "key": "d1d0c10c3196e811999cd7535f08bd16"
    }
  ]
}

Revokes given API keys.

Request Fields

Field Type Description
keys Array of Strings The API keys to be revoked

Response Format

The response is a JSON representation of information about the revocation of the listed API keys.

Response Fields (per API Key)

Field Type Description
revoked Boolean States whether the API key was successfully revoked
key String The API key that was revoked

Create API Key

Sample request

POST "https://api.fireflyiot.com/api/v1/apikeys?auth=secretapikey"
{
  "key": {
    "name": "test",
    "rate_scale": 20,
    "rate_limit": 20
  }
}

Sample response

{
  "apikey": {
    "valid_until": "2017-05-17T12:02:21.614030",
    "rate_scale": 20,
    "rate_limit": 20,
    "organization_id": 36,
    "name": "test",
    "may_be_modified": false,
    "key": "a4bb2cbcb07dd56ddd996374f7415b54",
    "created_at": "2017-02-16T12:02:21.633122"
  }
}

Creates a new API key in the organization to which the currently used API key is assigned.

Response Format

The response is a JSON representation of an API key.

Response Fields

Field Type Description
valid_until Date ISO date of the point in time when this API key becomes automatically revoked
rate_scale Integer Time window for rate limiting
rate_limit Integer Number of allowed calls in rate limit time window
organization_id Integer ID of the organization for which the API key was issued
name String Name
may_be_modified Boolean States whether this API key can be changed by the organization it was issued for
key String The actual value of the API key, to be used as a credential
created_at Date Date of when the API key was created

Create API Key in Organization

Sample request

POST "https://api.fireflyiot.com/api/v1/apikeys/organization/36?auth=secretapikey"
{
  "key": {
    "name": "test",
    "rate_scale": 20,
    "rate_limit": 20
  }
}

Sample response

{
  "apikey": {
    "valid_until": "2017-05-17T12:02:21.614030",
    "rate_scale": 20,
    "rate_limit": 20,
    "organization_id": 36,
    "name": "test",
    "may_be_modified": false,
    "key": "a4bb2cbcb07dd56ddd996374f7415b54",
    "created_at": "2017-02-16T12:02:21.633122"
  }
}

Creates a new API key in the specified organization.

Response Format

The response is a JSON representation of an API key.

Response Fields

Field Type Description
valid_until Date ISO date of the point in time when this API key becomes automatically revoked
rate_scale Integer Time window for rate limiting
rate_limit Integer Number of allowed calls in rate limit time window
organization_id Integer ID of the organization for which the API key was issued
name String Name
may_be_modified Boolean States whether this API key can be changed by the organization it was issued for
key String The actual value of the API key, to be used as a credential
created_at Date Date of when the API key was created

Statistics

API that provides statistical data for up packets in devices and organizations. Meant to be plugged into 3rd party billing application.

Example output

{
  "buckets": [
    {
      "packets": 1913,
      "date": "2016-10-01T00:00:00Z",
      "bytes": 44813
    },
    {
      "packets": 8615,
      "date": "2016-11-01T00:00:00Z",
      "bytes": 249863
    },
    {
      "packets": 0,
      "date": "2016-12-01T00:00:00Z",
      "bytes": 0
    },
    {
      "packets": 659,
      "date": "2017-01-01T00:00:00Z",
      "bytes": 19119
    }
  ]
}

Devices

Device stats URL

GET https://api.fireflyiot.com/api/v1/statistics/devices/{eui}?auth={secretapikey}

Used to query for statistics over a single device.

Organizations

Organization stats URL

GET https://api.fireflyiot.com/api/v1/statistics/organizations/{org id}?auth={secretapikey}

Used to query for statistics over all devices (recursively) in an organization.

Options

Field Type Description
after date (Organizations) Only return statistics for the time after the given date. Can be combined with before to query for a range.
before date (Organizations) Only return statistics for the time before the given date. Can be combined with after to query for a range.
interval day / month (Organizations, Devices) Interval of the buckets.
fill_missing boolean (Organizations, Devices) true by default. For device queries, this will detects buckets that are missing from the database output and populate them with 0 values.

MQTT

Create a MQTT subscription for organization_up_packets

POST "https://api.fireflyiot.com/api/v1/subscriptions?auth=secretapikey"
{
  "subscription": {
    "name": "foobar",
    "organization_id": 8,
    "bindings": [{
      "type": "organization_up_packets",
      "opts": {
        "organization": 8
      },
      "template_id": 1
    }],
    "queues": [{
      "type": "mqtt"
    }]
  }
}

You can use MQTT to receive events from your devices in real time.

To enable MQTT you first have to create a subscription with a queue of type mqtt.

Field Type Description
name String Name your subscription
organization_id Integer ID of your organization
bindings.type String Type of the binding. possible values
bindings.opts Object Options that depend on the binding type (here: organization ID)

See the sections about bindings, queues, and templates to learn more about subscription configuration. For most applications binding type organization_up_packets and the default template template_id: 1 should be sufficient, so the only parameters you have to replace in the sample request on the right are the subscription name and your organization ID.

Sample response

{
  "subscription": {
    "queues": [
      {
        "uid": "eeb95e33-d1ba-4a46-b22f-0c27a5955e53",
        "opts": {
          "access_key": "e944c8bf28b7f036a0dc20b5024e2e3a"
        }
      }
    ]
  }
}

In the response to your create-subscription-request you will (among other things) find your subscription queue’s uid and access_key. These are your credentials to connect to the Firefly MQTT broker. The broker runs through our RabbitMQ server and uses virtual hosts to separate data.

MQTT Connection Parameter
Host rabbithole.fireflyiot.com
Port 1883
Port (TLS) 8883 Client needs to trust Let’s Encrypt CA
User {uid}:{uid}
Password {access_key}
Topics Filtered: organizations/{organization_id}/devices/{eui}
All: organizations/+/devices/+

Using the connection parameters above you can now connect and subscribe to topics in the format organizations/{organization_id}/devices/{eui}. To receive events from more than one device/organization use the wildcard + for organization_id and/or eui.

Connect to the MQTT broker using the mosquitto client

mosquitto_sub -v \
  -t 'organizations/+/devices/+' \
  -h rabbithole.fireflyiot.com \
  -p 8883 \
  -u 'eeb95e33-d1ba-4a46-b22f-0c27a5955e53:eeb95e33-d1ba-4a46-b22f-0c27a5955e53' \
  -P 'e944c8bf28b7f036a0dc20b5024e2e3a' \
  --cafile /etc/ssl/cert.pem

Subscriptions (WebSocket, Webhook, Polling, MQTT)

Subscriptions allow you to fine-tune which events are sent where.

Subscriptions can be set up with a REST API.

Subscription Object

Field Type Description
id integer (read only) Unique ID of the subscription
name string Human-readable name of the subscription
bindings array List of bindings, see: Binding Object
queues array List of queues, see: Queue Object
organization_id integer Unique ID of the organization this subscription is attached to

List all subscriptions

Sample request

GET "https://api.fireflyiot.com/api/v1/subscriptions?auth={secretapikey}"

Sample response

{
    "subscriptions": [
        {
            "bindings": [
                {
                    "id": 22,
                    "opts": {
                        "device_eui": null,
                        "id": "6d7fa8f9-6d3f-42a8-92f3-bc0cd6f3b98d",
                        "include_suborganizations": null,
                        "organization": -1
                    },
                    "subscription_id": 3,
                    "template_id": 2,
                    "type": "organization_up_packets"
                }
            ],
            "id": 3,
            "name": "test",
            "organization_id": -1,
            "queues": [
                {
                    "opts": {},
                    "subscription_id": 3,
                    "type": "websocket",
                    "uid": "eeb95e33-d1ba-4a46-b22f-0c27a5955e53"
                }
            ]
        }
    ]
}

Will list all subscriptions of the organization the used API key is bound to.

Endpoint GET /api/v1/subscriptions?auth={secretapikey}

Returns

Field Type Description
subscriptions array List of subscriptions, see: Subscription Object

Create Subscription

Sample request

POST "https://api.fireflyiot.com/api/v1/subscriptions?auth=secretapikey"
{
  "subscription": {
    "name": "foobar",
    "organization_id": 8,
    "bindings": [{
      "type": "organization_up_packets",
      "opts": {
        "organization": 8
      },
      "template_id": 1
    }],
    "queues": [{
      "type": "websocket"
    }]
  }
}

Creates a new subscription. You don’t need to define bindings or queues right away, you can also add them later with the respective API methods for:

If you choose to not configure queues or bindings right away, pass an empty list [].

Endpoint POST /api/v1/subscriptions?auth={secretapikey}

Request body JSON object with this field:

Field Type
subscription Subscription object

Update Subscription

Update a subscription by using PUT on its URL and passing only the values you want to change.

Endpoint PUT /api/v1/subscriptions/{subscription_id}?auth={secretapikey}

Request body JSON object with this field:

Field Type
subscription Subscription object

Delete Subscription

Endpoint DELETE /api/v1/subscriptions/{subscription_id}?auth={secretapikey}

Subscription Bindings

A binding defines which events should be passed to a subscription’s queues.

Binding Object

Example binding object

{
  "id": 1,
  "type": "organization_up_packets",
  "opts": {
    "organization": 12
  },
  "template_id": 52,
  "subscription_id": 31
}
Field Type Description
id Integer (read only) Unique ID of the binding
type String Type of the binding. possible values
opts Object Options that depend on the type
template_id Integer ID of the template that renders this binding’s payload
subscription_id Integer ID of the subscription of this binding

Binding Types

Organization level types

Example organization opts

{
  "organization": 32
}

Generally, organization level types will bind to all packets in all devices of the organization specified in opts and its suborganizations.

Options

Field Type Description
organization Integer ID of the organization

Device level types

Example device opts

{
  "device_eui": "3DA6B1B33D2C0CCA"
}

Device level types will bind to all packets in one device.

Options

Field Type Description
device_eui String Base16 encoded big endian EUI of the device.

Create Binding

Endpoint POST /api/v1/subscriptions/{organization_id}/bindings?auth={secretapikey}

Request Body JSON with these fields:

Field Type
binding Binding object

Update Binding

You can edit a binding later if you want to change properties. Like with all other update API methods, you only have to pass the fields you want to change.

Endpoint PUT /api/v1/subscriptions/{organization_id}/bindings/{binding_id}?auth={secretapikey}

Request Body Same as Add binding, but you can omit fields that you don’t want to edit.

Response Body A JSON Object with a field binding, containing a Binding object. This represents the binding after your changes have been applied to it.

Delete Binding

Use this to remove a binding from a subscription.

Endpoint DELETE /api/v1/subscriptions/{organization_id}/bindings/{binding_id}?auth={secretapikey}

Subscription Queues

Queue Object

Example queue object

{
  "uid": "eeb95e33-d1ba-4a46-b22f-0c27a5955e53",
  "type": "http_push",
  "subscription_id": 12,
  "opts": {
    "url": "http://api.iot-app.io/push/",
    "method": "POST"
  }
}
Field Type Description
uid UUID (read-only) Unique ID of the queue
type String Type of the queue. possible values
subscription_id Integer ID of the queue’s subscription
opts Object Options for the queue that depend on its type

Queue Types

The queue type decides how the events and messages get to your application.

We currently offer http_push (webhook), websocket, http_pull (polling) and mqtt.

http_push

Pushes all events to an external HTTP server.

It is recommended to use HTTPS to prevent bad people from eaves-dropping on your data.

Options

Field Type Description
method String HTTP method to use (GET, POST, PUT, DELETE, PATCH)
url String HTTP URL to push to
headers Object key-value list of headers to use in the HTTP request.

websocket

WebSocket endpoint that sends events as they happen.

After creation, a client can connect to wss://api.fireflyiot.com/api/v1/subscriptions/websocket/{uid}, where {uid} is replaced with whatever uid was returned by the API.

The queue will only start accumulating messages after the first client has connected to the WebSocket.

In case of disconnects, messages will be stored until the client reconnects or 2 hours have passed, whichever comes first. This allows clients to recover from crashes or restarts without missing any events.

It is possible to connect multiple clients to the same WebSocket, in which case messages are distributed equally in a round-robin fashion.

If you want all clients to receive all messages, you need to create a queue for each client.

http_pull

HTTP endpoint to poll for new messages.

Use GET https://api.fireflyiot.com/api/v1/subscriptions/http_pull/<uid>?auth=<apikey> to get new events. Similar to the WebSocket queue, events will only be kept for 2 hours.

Options

You can pass the following query parameters when calling the URL.

encoding (String) Decides how the payload should be formatted in the HTTP Body.

Possible values:

separator (String) Overrides the separation string when the encoding is not json.

limit (Integer) Defines the maximum amount of messages to return. If not set, will return all messages.

mqtt

MQTT endpoint to subscribe to events.

When creating an MQTT subscription the API will respond with an access_key in the opts field along with the uid. See the MQTT Section for details.

Create Queue

Endpoint POST /api/v1/subscriptions/{subscription_id}/queues?auth={secretapikey}

Request Body JSON object with a field queue that contains a Queue Object, the uid field is generated automatically

Show Queue

Endpoint GET /api/v1/subscriptions/{subscription_id}/queues/{queue_uid}?auth={secretapikey}

List all queues of subscription

Endpoint GET /api/v1/subscriptions/{subscription_id}/queues?auth={secretapikey}

Update Queue

Endpoint PUT /api/v1/subscriptions/{subscription_id}/queues/{queue_uid}?auth={secretapikey}

Request Body JSON object with field queue that contains all the values you want to overwrite. See: Queue Object

Delete Queue

Endpoint DELETE /api/v1/subscriptions/{subscription_id}/queues/{queue_uid}?auth={secretapikey}

Subscription Templates

Each binding has a template which is used to format each message that was received over it.

Template Object

Example object

{
  "id": 45,
  "name": "Device JSON",
  "source": "<%= Poison.encode!(@subject) %>",
  "organization_id": 31,
  "visibility": "public",
  "code_type": "eex"
}
Field Type Description
id Integer (read only) Unique ID of the template
name String Human readable name of the template. Used to identify it in the UI.
source String Source code of the template. Language depends on code_type field
organization_id Integer ID of the organization the template is bound to
visibility String Visibility of the template to other organizations. Possible values
code_type String Language of the source code. Possible values

Template Language

Templates currently support code written the following languages:

Language code_type Documentation
Elixir ex Homepage
Embedded Elixir eex HexDocs

When creating or updating a template, the code will be checked for allowed function calls and modules.

Allowed Modules

Allowed Functions

The following functions of the Kernel module are whitelisted:

Template Visibility

List Templates

Endpoint GET /api/v1/templates?auth={secretapikey}

Lists all templates that are visible to the organization the given secretapikey is bound to.

Create Template

Endpoint POST /api/v1/templates?auth={secretapikey}

Request Body JSON object with a field template that contains a Template Object

Update Template

Endpoint PUT /api/v1/templates/{template_id}?auth={secretapikey}

Request Body JSON object with field template that contains all the values you want to overwrite. See: Template Object

Delete Template

Endpoint DELETE /api/v1/templates/{template_id}?auth={secretapikey}

WebSocket API (deprecated)

The WebSocket API has been deprecated in favor of subscriptions. To continue using WebSockets, create a subscription with a websocket queue.

General

The Firefly websocket API allows for real-time streaming of packets as they are received by the application server. A HTTP websocket connection needs to be established with wss://api.fireflyiot.com/api/websocket.

Authentication

The Firefly websocket API uses the same API keys that are used for the REST API.

Use the API key as a connection parameter like wss://api.fireflyiot.com/api/websocket?auth=secretapikey.

Libraries

To connect to the application server channels, you will need to use a Phoenix Channels-compatible library.

JavaScript

var phoenix = require("./phoenix-common.js")
var socket = new phoenix.Socket("wss://api.fireflyiot.com/api", {
  transport: require("websocket").w3cwebsocket,
  params: {auth: "206b02ed500addc57bb12244151d6a7a"
}})

socket.connect()
socket.onError(function(err) {console.log("error:", err)})

var channel = socket.channel("device:000000001EE00001", {
  received_after: "2016-08-02 00:00:00"
})

channel.join()
    .receive("ok", function() {console.log("joined")})
    .receive("error", function(reason) {console.log("error:", reason)})

channel.on("packets", function(message) {console.log("message", message)})

To connect via JavaScript, you can either use the JavaScript supplied with the Phoenix Framework or use the ready-to-use Phoenix channels JavaScript client library that we supply at digimondo/phoenix-websocket-js, called phoenix-common.js.

Channels

Once connected, you can subscribe to channels which will expose received packets for each device.

Device Channels

Connect to device:<eui>, e.g. device:00000000413B9F61 to receive packet updates for the device with the corresponding EUI.

Device Class Channels

Connect to device_class:<id>, e.g. device_class:1 to receive device updates for the device class with the corresponding ID.