Files
meshview/docs/API_Documentation.md
T

12 KiB

API Documentation

Base URL: http(s)://<host>

All endpoints return JSON. Timestamps are either ISO 8601 strings or *_us values in microseconds since epoch.

1. Nodes API

GET /api/nodes

Returns a list of nodes, with optional filtering.

Query Parameters

  • node_id (optional, int): Exact node ID.
  • role (optional, string): Node role.
  • channel (optional, string): Channel name.
  • hw_model (optional, string): Hardware model.
  • days_active (optional, int): Nodes seen within the last N days.

Response Example

{
  "nodes": [
    {
      "id": 42,
      "node_id": 1234,
      "long_name": "Alice",
      "short_name": "A",
      "hw_model": "T-Beam",
      "firmware": "1.2.3",
      "role": "client",
      "last_lat": 377749000,
      "last_long": -1224194000,
      "channel": "main",
      "last_seen_us": 1736370123456789
    }
  ]
}

2. Packets API

GET /api/packets

Returns packets with optional filters.

Query Parameters

  • packet_id (optional, int): Return exactly one packet (overrides other filters).
  • limit (optional, int): Max packets to return, clamped 1-1000. Default: 50.
  • since (optional, int): Only packets imported after this microsecond timestamp.
  • portnum (optional, int): Filter by port number.
  • contains (optional, string): Payload substring filter.
  • from_node_id (optional, int): Filter by sender node ID.
  • to_node_id (optional, int): Filter by recipient node ID.
  • node_id (optional, int): Legacy filter matching either from or to node ID.

Response Example

{
  "packets": [
    {
      "id": 123,
      "import_time_us": 1736370123456789,
      "channel": "main",
      "from_node_id": 5678,
      "to_node_id": 91011,
      "portnum": 1,
      "long_name": "Alice",
      "payload": "Hello, Bob!",
      "to_long_name": "Bob",
      "reply_id": 122
    }
  ],
  "latest_import_time": 1736370123456789
}

Notes

  • For portnum=1 (text messages), packets are filtered to remove sequence-only payloads.
  • latest_import_time is returned when available for incremental polling (microseconds).

3. Channels API

GET /api/channels

Returns channels seen in a time period.

Query Parameters

  • period_type (optional, string): hour or day. Default: hour.
  • length (optional, int): Number of periods to look back. Default: 24.

Response Example

{
  "channels": ["LongFast", "MediumFast", "ShortFast"]
}

4. Stats API

GET /api/stats

Returns packet statistics aggregated by time periods, with optional filtering.

Query Parameters

  • period_type (optional, string): hour or day. Default: hour.
  • length (optional, int): Number of periods to include. Default: 24.
  • channel (optional, string): Filter by channel (case-insensitive).
  • portnum (optional, int): Filter by port number.
  • to_node (optional, int): Filter by destination node ID.
  • from_node (optional, int): Filter by source node ID.
  • node (optional, int): If provided, return combined sent and seen totals for that node.

Response Example (series)

{
  "period_type": "hour",
  "length": 24,
  "channel": "LongFast",
  "portnum": 1,
  "to_node": 12345678,
  "from_node": 87654321,
  "data": [
    { "period": "2025-08-08 14:00", "count": 10 },
    { "period": "2025-08-08 15:00", "count": 7 }
  ]
}

Response Example (node totals)

{
  "node_id": 12345678,
  "period_type": "hour",
  "length": 24,
  "sent": 42,
  "seen": 58
}

GET /api/stats/count

Returns total packet counts, optionally filtered.

Query Parameters

  • packet_id (optional, int): Filter packet_seen by packet ID.
  • period_type (optional, string): hour or day.
  • length (optional, int): Number of periods to include.
  • channel (optional, string): Filter by channel.
  • from_node (optional, int): Filter by source node ID.
  • to_node (optional, int): Filter by destination node ID.

Response Example

{
  "total_packets": 12345,
  "total_seen": 67890
}

GET /api/stats/top

Returns nodes sorted by packets seen, with pagination.

Query Parameters

  • period_type (optional, string): hour or day. Default: day.
  • length (optional, int): Number of periods to include. Default: 1.
  • channel (optional, string): Filter by channel.
  • limit (optional, int): Max nodes to return. Default: 20, max 100.
  • offset (optional, int): Pagination offset. Default: 0.

Response Example

{
  "total": 250,
  "limit": 20,
  "offset": 0,
  "nodes": [
    {
      "node_id": 1234,
      "long_name": "Alice",
      "short_name": "A",
      "channel": "main",
      "sent": 100,
      "seen": 240,
      "avg": 2.4
    }
  ]
}

5. Edges API

GET /api/edges

Returns network edges (connections between nodes) based on traceroutes and neighbor info. Traceroute edges are collected over the last 12 hours. Neighbor edges are based on port 71 packets.

A completed traceroute is observed as a response packet, whose from/to are reversed with respect to the traced path, so edges are built as to -> route[] -> from. route[] may contain 0xFFFFFFFF placeholders for hops the mesh could not identify; the edges on either side of such a placeholder are omitted, because the nodes around an unknown hop are not neighbours.

Query Parameters

  • type (optional, string): traceroute or neighbor. If omitted, returns both.
  • node_id (optional, int): Filter edges to only those touching a node.

Response Example

{
  "edges": [
    { "from": 12345678, "to": 87654321, "type": "traceroute" },
    { "from": 11111111, "to": 22222222, "type": "neighbor" }
  ]
}

6. Config API

GET /api/snapshots/daily

Returns stored daily snapshots. For new snapshots, packet_count is the number of packet records imported during date (00:00 UTC inclusive to the next midnight exclusive). The scheduled capture records the previous complete UTC day. Repeated observations of the same packet are not counted separately. node_count counts distinct packet senders whose packets were imported or observed during that UTC day (including observations of previously imported packets). gateway_count counts distinct MQTT gateways with packet observations imported during that day. These are activity counts, not database totals; recipients alone do not count as active nodes. Activity uses local import timestamps, not device timestamps. Older snapshots retain their originally stored counts and are not automatically converted. Counts depend on the packet and observation history still retained at capture time.

GET /api/config

Returns a safe subset of server configuration.

site.map_channel_colors contains channel color overrides from the optional [map_channel_colors] INI section. Each entry is channel = #RRGGBB; invalid colors are omitted. Channel matching on the map ignores case, spaces, hyphens, and underscores. Unlisted channels use generated colors. For example:

[map_channel_colors]
LongFast = #4363d8
LocalChat = #18aa18

Restart the web server and reload the map after changing these settings. Omitting the section uses generated colors for every channel.

Response Example

{
  "site": {
    "domain": "example.com",
    "language": "en",
    "title": "Meshview",
    "message": "",
    "starting": "/chat",
    "nodes": "true",
    "chat": "true",
    "everything": "true",
    "graphs": "true",
    "stats": "true",
    "net": "true",
    "map": "true",
    "top": "true",
    "map_top_left_lat": 39.0,
    "map_top_left_lon": -123.0,
    "map_bottom_right_lat": 36.0,
    "map_bottom_right_lon": -121.0,
    "map_interval": 3,
    "firehose_interval": 3,
    "weekly_net_message": "Weekly Mesh check-in message.",
    "net_tag": "#BayMeshNet",
    "version": "3.0.0"
  },
  "mqtt": {
    "server": "mqtt.example.com",
    "topics": ["msh/region/#"]
  },
  "cleanup": {
    "enabled": "false",
    "days_to_keep": "14",
    "hour": "2",
    "minute": "0",
    "vacuum": "false"
  }
}

7. Language API

GET /api/lang

Returns translation strings.

Query Parameters

  • lang (optional, string): Language code (e.g., en, es). Default from config or en.
  • section (optional, string): Return only one section (e.g., nodelist, firehose).

Response Example

{
  "title": "Meshview",
  "search_placeholder": "Search..."
}

8. Packets Seen API

GET /api/packets_seen/{packet_id}

Returns packet_seen entries for a packet.

Path Parameters

  • packet_id (required, int): Packet ID.

Response Example

{
  "seen": [
    {
      "packet_id": 123,
      "node_id": 456,
      "rx_time": "2025-07-22T12:45:00",
      "hop_limit": 7,
      "hop_start": 0,
      "channel": "main",
      "rx_snr": 5.0,
      "rx_rssi": -90,
      "topic": "msh/region/#",
      "import_time_us": 1736370123456789
    }
  ]
}

9. Traceroute API

GET /api/traceroute/{packet_id}

Returns traceroute details and derived paths for a packet.

Path Parameters

  • packet_id (required, int): Packet ID.

A completed traceroute is observed as a response packet, whose from/to are reversed with respect to the traced path. initiator and target resolve this: the forward path runs initiator -> forward_hops -> target and the return path runs target -> reverse_hops -> initiator, in both directions of travel. forward_hops and reverse_hops contain only the intermediate hops, never the endpoints.

A gateway usually reports a response that is still travelling home, so reverse_hops is often incomplete. reverse_complete says whether that observation had reached the initiator; only then does the corresponding winning_paths.reverse entry end at the initiator.

winning_paths is built from response observations, since a response proves the request reached the target. complete on a unique_forward_paths entry says whether some response reported that hop list, and so whether it is known to end at the target.

Response Example

{
  "packet": {
    "id": 123,
    "from": 222,
    "to": 111,
    "initiator": 111,
    "target": 222,
    "channel": "main"
  },
  "traceroute_packets": [
    {
      "index": 0,
      "gateway_node_id": 333,
      "done": true,
      "forward_hops": [444, 555],
      "reverse_hops": [555, 444],
      "reverse_complete": true
    }
  ],
  "unique_forward_paths": [
    { "path": [444, 555], "count": 2, "complete": true }
  ],
  "unique_reverse_paths": [
    [555, 444]
  ],
  "winning_paths": {
    "forward": [[111, 444, 555, 222]],
    "reverse": [[222, 555, 444, 111]]
  }
}

10. Health API

GET /health

Returns service health and database status.

Response Example

{
  "status": "healthy",
  "timestamp": "2025-07-22T12:45:00+00:00",
  "version": "3.0.3",
  "git_revision": "abc1234",
  "cleanup": {
    "enabled": true,
    "days_to_keep": 14,
    "scheduled_time": "02:00",
    "vacuum": false,
    "status": "ok",
    "status_file": "dbcleanup.status.json",
    "last_run": {
      "status": "ok",
      "started_at": "2026-06-04T09:00:00+00:00",
      "completed_at": "2026-06-04T09:00:03+00:00",
      "cutoff_at": "2026-05-21T09:00:00+00:00",
      "days_to_keep": 14,
      "vacuum_requested": false,
      "vacuum_completed": false,
      "rows_deleted": {
        "packet": 1200,
        "packet_seen": 3400,
        "traceroute": 42,
        "node": 3
      },
      "error": null
    }
  },
  "backup": {
    "enabled": true,
    "backup_dir": "./backups",
    "scheduled_time": "02:00",
    "status": "ok",
    "status_file": "dbbackup.status.json",
    "last_run": {
      "status": "ok",
      "started_at": "2026-06-04T09:00:00+00:00",
      "completed_at": "2026-06-04T09:00:02+00:00",
      "backup_dir": "./backups",
      "database_path": "packets.db",
      "backup_file": "backups/packets_backup_20260604_090000.db.gz",
      "original_size_bytes": 12939444,
      "compressed_size_bytes": 4211560,
      "compression_percent": 67.5,
      "error": null
    }
  },
  "database": "connected",
  "database_size": "12.34 MB",
  "database_size_bytes": 12939444
}

11. Version API

GET /version

Returns version metadata.

Response Example

{
  "version": "3.0.3",
  "release_date": "2026-1-15",
  "git_revision": "abc1234",
  "git_revision_short": "abc1234"
}