Skip to content

Message formats

Network Survey uses standardized message formats defined in the Network Survey Messaging library. This ensures consistency across MQTT (JSON) and gRPC (protobuf) protocols.

Network Survey streams data in two formats:

  • MQTT: JSON format (human-readable)
  • gRPC: Protocol Buffers format (binary, more compact)

Both formats use the same underlying message definitions from the Network Survey Messaging library. Network Survey 2.0 uses version 2.6.0 of the library, and every message it sends carries that number in its version field. Versions with NS Scout support use version 2.7.0, which adds WifiClientRecord.

Network Survey sends different message types for each technology:

  • Cellular: GsmRecord, CdmaRecord, UmtsRecord, LteRecord, NrRecord
  • Wi-Fi: WifiBeaconRecord
  • Wi-Fi clients (NS Scout only): WifiClientRecord, WifiProbeRequestRecord
  • Bluetooth: BluetoothRecord
  • GNSS: GnssRecord
  • Device status: DeviceStatus
  • Phone state: PhoneState
  • Wi-Fi watchlist: WatchlistMatch, WatchlistEntryUpdate (MQTT only)

Call records are never streamed; they only go to Log files. Over MQTT, PhoneState messages share the device_status_message topic with DeviceStatus, so check messageType to tell them apart.

Each message type has specific fields for that technology (e.g., MCC/MNC/PLMN for cellular, SSID/BSSID for Wi-Fi).

Here’s what an MQTT message looks like (LTE cellular record):

{
"version": "2.6.0",
"messageType": "LteRecord",
"data": {
"deviceSerialNumber": "1234",
"deviceName": "Craxiom Pixel",
"deviceTime": "2026-07-24T15:43:57.123456-04:00",
"latitude": 51.470334,
"longitude": -0.486594,
"altitude": 13.3,
"speed": 9.3,
"missionId": "NS 1234abc12e56789f 20260724-154325",
"recordNumber": 1,
"groupNumber": 1,
"accuracy": 40,
"locationAge": 1000,
"mcc": 311,
"mnc": 480,
"plmn": "311-480",
"tac": 52803,
"eci": 52824577,
"earfcn": 5230,
"pci": 234,
"rsrp": -107.0,
"rsrq": -11.0,
"snr": 19.0,
"ta": 27,
"signalStrength": -73.1,
"cqi": 7,
"servingCell": true,
"lteBandwidth": "MHZ_10",
"provider": "Verizon",
"slot": 2,
"connectionStatus": "PRIMARY_SERVING",
"cellBandwidthsKhz": [20000, 10000]
}
}

Key elements:

  • version: the Network Survey Messaging version the message was built with
  • messageType: type of record (LteRecord, WifiBeaconRecord, etc.)
  • data: the message payload with all fields

Fields with no value are left out of the JSON, and so are plain number, text and true/false fields at their default (0, empty or false), such as speed when the phone is not moving. For example, a Wi-Fi access point that Android listed without a measured signal has no signalStrength field.

  • LTE and NR records (2.5.0): connectionStatus says how the phone is connected to the cell (PRIMARY_SERVING, SECONDARY_SERVING or NEIGHBOR; absent when not reported), and cellBandwidthsKhz lists the bandwidth of each carrier the phone’s data connection was using, in kHz. Two or more entries mean carrier aggregation was active. It is only present on cells the phone was using.
  • Device status (2.6.0): gnssAge and networkAge give the age in milliseconds of the GNSS and network location fixes, and mockLocation is present, as true, only when the location came from a mock location provider.

The fields heading, pitch, roll, fieldOfView and receiverSensitivity were removed in version 2.0.0 and are never sent.


For detailed information on all message formats, fields, and usage, visit:

The official Network Survey Messaging documentation includes:

  • Complete field definitions for all message types
  • Detailed field descriptions including data types, ranges, and optional fields
  • Message versioning and compatibility information

The GitHub repository provides:

  • Protocol Buffer source files (.proto)
  • Java library for working with the message API
  • Version history and release notes