Flows API

The Flows API exposes aggregated traffic records stored in the flows-* indices. Three endpoints cover the common use cases.

Note

Flows are aggregated over 60-second tumbling windows before they're indexed. The smallest time-range that makes sense to query is therefore ~1 minute.

GET /api/v1/flows

Paginated, filterable list of aggregated flows.

Query parameters

from          i64       Start timestamp (epoch ms)
to            i64       End timestamp (epoch ms)
src_ip        string    Exact-match source IP
dst_ip        string    Exact-match destination IP
port          u16       Matches either src_port OR dst_port
protocol      u8        IANA protocol number (6=TCP, 17=UDP, 1=ICMP)
exporter      string    Exporter (gateway) IP
sort          string    "bytes" | "packets" | "timestamp"  (default: timestamp)
order         string    "asc" | "desc"                      (default: desc)
offset        usize     Pagination offset
limit         usize     Page size (default: 50)

Example

curl -H "Authorization: Bearer $TOKEN" \
  'https://siem.example.com/api/v1/flows?sort=bytes&order=desc&limit=10'

Response

{
  "total": 4821,
  "offset": 0,
  "limit": 10,
  "flows": [
    {
      "id": "f8d72...",
      "timestamp": 1776340800000,
      "window_start": 1776340740000,
      "window_end": 1776340800000,
      "src_ip": "10.0.0.5",
      "dst_ip": "1.1.1.1",
      "src_hostname": null,
      "dst_hostname": "one.one.one.one",
      "src_port": 50000,
      "dst_port": 443,
      "protocol": 6,
      "protocol_name": "TCP",
      "bytes": 54302,
      "packets": 87,
      "tcp_flags": 24,
      "first_seen_ms": 1776340745123,
      "last_seen_ms": 1776340799845,
      "exporter_ip": "10.0.0.1",
      "version": 9
    }
  ]
}

GET /api/v1/flows/top-talkers

Terms aggregation — returns the top N source/destination/pair IPs over a window, ranked by bytes or packets.

Query parameters

window_secs   i64       Look-back window  (default: 3600 = 1 hour)
by            string    "bytes" | "packets"  (default: bytes)
dim           string    "src" | "dst" | "pair"  (default: src)
limit         usize     Max rows  (default: 20)

Example — top bandwidth consumers in the last hour

curl -H "Authorization: Bearer $TOKEN" \
  'https://siem.example.com/api/v1/flows/top-talkers?window_secs=3600&by=bytes&dim=pair'

Response

[
  { "key": "10.0.0.5 → 142.250.72.46", "bytes": 4823091823, "packets": 3921047, "flow_count": 147 },
  { "key": "10.0.0.18 → 1.1.1.1",       "bytes": 2104832019, "packets": 1478293, "flow_count": 203 },
  ...
]

GET /api/v1/flows/protocols

Protocol breakdown: bytes, packets, and flow count per IANA protocol over a window.

Query parameters

window_secs   i64   Look-back window (default: 3600)

Response

[
  { "protocol": "TCP",  "bytes": 18390482192, "packets": 14829103, "flow_count": 8294 },
  { "protocol": "UDP",  "bytes":  2938471029, "packets":  4821093, "flow_count": 3021 },
  { "protocol": "ICMP", "bytes":       82031, "packets":     1921, "flow_count":   84 }
]

Index Structure

Flows are stored in daily indices (e.g. unifi-sentinel-flows-2026.04.16) created from an index template at startup. Mappings use ip types for src_ip/dst_ip/exporter_ip and long for bytes/packets.