mirror of
https://github.com/MeshCore-Beacon/beacon-server.git
synced 2026-09-09 13:35:34 +00:00
1168 lines
29 KiB
YAML
1168 lines
29 KiB
YAML
basePath: /api/v1
|
|
definitions:
|
|
api.Channel:
|
|
properties:
|
|
channelHash:
|
|
description: hex-encoded single-byte hash
|
|
type: string
|
|
hashtag:
|
|
description: 'tag name without # prefix'
|
|
type: string
|
|
id:
|
|
type: integer
|
|
isHashtag:
|
|
description: true if derived from a hashtag PSK
|
|
type: boolean
|
|
keyFingerprint:
|
|
description: first 8 bytes of SHA256(key), hex-encoded
|
|
type: string
|
|
keyKnown:
|
|
description: true if Tower has a decryption key
|
|
type: boolean
|
|
lastSeen:
|
|
description: epoch ms
|
|
type: integer
|
|
messageCount:
|
|
type: integer
|
|
name:
|
|
description: display name, nil if not set
|
|
type: string
|
|
type: object
|
|
api.IATA:
|
|
properties:
|
|
displayName:
|
|
type: string
|
|
iata:
|
|
type: string
|
|
lat:
|
|
type: number
|
|
lon:
|
|
type: number
|
|
type: object
|
|
api.Node:
|
|
properties:
|
|
firstSeen:
|
|
description: epoch ms
|
|
type: integer
|
|
id:
|
|
type: string
|
|
lastAdvertAt:
|
|
description: epoch ms, nil if no advert received
|
|
type: integer
|
|
lastSeen:
|
|
description: epoch ms
|
|
type: integer
|
|
lat:
|
|
type: number
|
|
lng:
|
|
type: number
|
|
locationSource:
|
|
description: e.g. "advert", "manual"
|
|
type: string
|
|
metadata:
|
|
description: raw JSONB metadata
|
|
minFirmwareVersion:
|
|
description: derived from capability flags
|
|
type: string
|
|
name:
|
|
type: string
|
|
nodeType:
|
|
description: 1=companion, 2=repeater, 3=room server
|
|
type: integer
|
|
nodeTypeName:
|
|
type: string
|
|
publicKey:
|
|
description: hex-encoded public key
|
|
type: string
|
|
supportsMultibytePaths:
|
|
description: firmware >= 1.14.0
|
|
type: boolean
|
|
supportsMultibyteTraces:
|
|
description: firmware >= 1.11.0
|
|
type: boolean
|
|
type: object
|
|
api.ObservationPoint:
|
|
properties:
|
|
activeObservers:
|
|
type: integer
|
|
hour:
|
|
description: epoch ms, start of bucket
|
|
type: integer
|
|
iata:
|
|
type: string
|
|
observationCount:
|
|
type: integer
|
|
uniquePackets:
|
|
type: integer
|
|
type: object
|
|
api.Observer:
|
|
properties:
|
|
batteryLevel:
|
|
description: volts, nil if mains powered
|
|
type: number
|
|
brokers:
|
|
description: broker names this observer has been seen on
|
|
items:
|
|
$ref: '#/definitions/api.ObserverBroker'
|
|
type: array
|
|
displayName:
|
|
description: friendly name from /status messages
|
|
type: string
|
|
firmwareBuild:
|
|
type: string
|
|
firmwareVersion:
|
|
type: string
|
|
firstSeen:
|
|
description: epoch ms
|
|
type: integer
|
|
hardwareModel:
|
|
type: string
|
|
iata:
|
|
description: most recently heard IATA
|
|
type: string
|
|
id:
|
|
type: string
|
|
lastSeen:
|
|
description: epoch ms
|
|
type: integer
|
|
lastStatusAt:
|
|
description: epoch ms
|
|
type: integer
|
|
observationCount:
|
|
type: integer
|
|
observerType:
|
|
description: e.g. "meshcoretomqtt", "meshcoreha"
|
|
type: string
|
|
publicKey:
|
|
description: hex-encoded public key
|
|
type: string
|
|
radioBwKhz:
|
|
description: bandwidth in kHz
|
|
type: number
|
|
radioCr:
|
|
description: coding rate denominator
|
|
type: integer
|
|
radioFreqMhz:
|
|
description: MHz e.g. 910.525
|
|
type: number
|
|
radioSf:
|
|
description: LoRa spreading factor
|
|
type: integer
|
|
softwareVersion:
|
|
type: string
|
|
status:
|
|
description: '"online" or "offline" derived from last_status_at'
|
|
type: string
|
|
statusMetadata:
|
|
description: raw /status JSON payload
|
|
uptimeSeconds:
|
|
type: integer
|
|
type: object
|
|
api.ObserverBroker:
|
|
properties:
|
|
lastPacketAt:
|
|
description: epoch ms, last packet received via this broker; 0 if none
|
|
type: integer
|
|
lastSeenAt:
|
|
description: epoch ms, last time observer was seen on this broker
|
|
type: integer
|
|
name:
|
|
description: broker name e.g. "mqtt1"
|
|
type: string
|
|
type: object
|
|
api.ObserverTelemetry:
|
|
properties:
|
|
interval:
|
|
type: string
|
|
points:
|
|
items:
|
|
$ref: '#/definitions/api.ObserverTelemetryPoint'
|
|
type: array
|
|
range:
|
|
type: string
|
|
type: object
|
|
api.ObserverTelemetryPoint:
|
|
properties:
|
|
airtimeRxPct:
|
|
type: number
|
|
airtimeTxPct:
|
|
type: number
|
|
batteryMv:
|
|
type: integer
|
|
noiseFloorDb:
|
|
type: number
|
|
queueLength:
|
|
type: integer
|
|
receiveErrors:
|
|
type: integer
|
|
t:
|
|
description: epoch ms
|
|
type: integer
|
|
uptimeSeconds:
|
|
type: integer
|
|
type: object
|
|
api.Packet:
|
|
properties:
|
|
channelHash:
|
|
description: hex-encoded
|
|
type: string
|
|
decrypted:
|
|
type: boolean
|
|
firstHeardAt:
|
|
description: epoch ms
|
|
type: integer
|
|
lastHeardAt:
|
|
description: epoch ms
|
|
type: integer
|
|
observationCount:
|
|
type: integer
|
|
observations:
|
|
items:
|
|
$ref: '#/definitions/api.PacketObservationDetail'
|
|
type: array
|
|
originPubkey:
|
|
description: hex-encoded
|
|
type: string
|
|
packetHash:
|
|
description: hex-encoded
|
|
type: string
|
|
parsedPayload: {}
|
|
payloadType:
|
|
type: integer
|
|
payloadTypeName:
|
|
type: string
|
|
payloadVersion:
|
|
type: integer
|
|
rawPayload:
|
|
description: hex-encoded
|
|
type: string
|
|
routeType:
|
|
type: integer
|
|
routeTypeName:
|
|
type: string
|
|
transportCodes:
|
|
description: hex-encoded
|
|
type: string
|
|
type: object
|
|
api.PacketObservationDetail:
|
|
properties:
|
|
hashSize:
|
|
type: integer
|
|
heardAt:
|
|
description: epoch ms
|
|
type: integer
|
|
hopCount:
|
|
type: integer
|
|
iata:
|
|
type: string
|
|
id:
|
|
type: integer
|
|
observerId:
|
|
type: string
|
|
observerName:
|
|
type: string
|
|
pathBytes:
|
|
description: hex-encoded
|
|
type: string
|
|
pathLengthByte:
|
|
type: integer
|
|
propagationTimeMs:
|
|
type: integer
|
|
radio:
|
|
$ref: '#/definitions/api.PacketRadio'
|
|
resolvedPath:
|
|
items:
|
|
$ref: '#/definitions/api.ResolvedHop'
|
|
type: array
|
|
rssi:
|
|
type: integer
|
|
snr:
|
|
type: number
|
|
sourceBroker:
|
|
type: string
|
|
type: object
|
|
api.PacketRadio:
|
|
properties:
|
|
bandwidthKhz:
|
|
type: number
|
|
codingRate:
|
|
type: integer
|
|
freqMhz:
|
|
type: number
|
|
spreadFactor:
|
|
type: integer
|
|
type: object
|
|
api.PayloadBreakdownItem:
|
|
properties:
|
|
count:
|
|
type: integer
|
|
payloadType:
|
|
type: integer
|
|
payloadTypeName:
|
|
type: string
|
|
type: object
|
|
api.Region:
|
|
properties:
|
|
centerLat:
|
|
description: map center latitude
|
|
type: number
|
|
centerLng:
|
|
description: map center longitude
|
|
type: number
|
|
description:
|
|
type: string
|
|
iatas:
|
|
description: member IATA codes
|
|
items:
|
|
type: string
|
|
type: array
|
|
id:
|
|
type: integer
|
|
name:
|
|
type: string
|
|
slug:
|
|
description: URL-safe identifier e.g. "western-canada"
|
|
type: string
|
|
zoomLevel:
|
|
description: suggested map zoom level
|
|
type: integer
|
|
type: object
|
|
api.RegionSummary:
|
|
properties:
|
|
id:
|
|
type: integer
|
|
name:
|
|
type: string
|
|
slug:
|
|
description: URL-safe identifier e.g. "western-canada"
|
|
type: string
|
|
type: object
|
|
api.ResolvedHop:
|
|
properties:
|
|
confidence:
|
|
description: '"high", "low", "unknown"'
|
|
type: string
|
|
node:
|
|
$ref: '#/definitions/api.ResolvedNode'
|
|
type: object
|
|
api.ResolvedNode:
|
|
properties:
|
|
id:
|
|
type: string
|
|
latitude:
|
|
type: number
|
|
longitude:
|
|
type: number
|
|
name:
|
|
type: string
|
|
publicKey:
|
|
description: hex-encoded prefix
|
|
type: string
|
|
type: object
|
|
api.StatsOverview:
|
|
properties:
|
|
activeIatas:
|
|
type: integer
|
|
activeObservers:
|
|
type: integer
|
|
totalObservations:
|
|
type: integer
|
|
totalPackets:
|
|
type: integer
|
|
windowHours:
|
|
description: always 24 for now
|
|
type: integer
|
|
type: object
|
|
api.TopNode:
|
|
properties:
|
|
iata:
|
|
type: string
|
|
lastHeard:
|
|
description: epoch ms
|
|
type: integer
|
|
nodeId:
|
|
type: string
|
|
nodeName:
|
|
type: string
|
|
nodeType:
|
|
type: integer
|
|
nodeTypeName:
|
|
type: string
|
|
observationCount:
|
|
type: integer
|
|
type: object
|
|
api.TopObserver:
|
|
properties:
|
|
displayName:
|
|
type: string
|
|
iata:
|
|
type: string
|
|
observationCount:
|
|
type: integer
|
|
observerId:
|
|
type: string
|
|
observerType:
|
|
type: string
|
|
type: object
|
|
handlers.APIError:
|
|
properties:
|
|
code:
|
|
description: e.g. "not_found", "bad_request"
|
|
type: string
|
|
message:
|
|
description: e.g. "channel not found"
|
|
type: string
|
|
type: object
|
|
handlers.BrokerStatus:
|
|
properties:
|
|
connected:
|
|
type: boolean
|
|
name:
|
|
type: string
|
|
type: object
|
|
host: localhost:8080
|
|
info:
|
|
contact:
|
|
name: MeshCore Tower
|
|
url: https://github.com/MeshCore-Tower/tower-server
|
|
description: MeshCore network observation backend. Ingests LoRa packets from MQTT
|
|
brokers, stores in PostgreSQL, and streams live events via WebSocket.
|
|
license:
|
|
name: MIT
|
|
termsOfService: https://github.com/MeshCore-Tower/tower-server
|
|
title: MeshCore Tower API
|
|
version: "1.0"
|
|
paths:
|
|
/brokers:
|
|
get:
|
|
produces:
|
|
- application/json
|
|
responses:
|
|
"200":
|
|
description: OK
|
|
schema:
|
|
items:
|
|
$ref: '#/definitions/handlers.BrokerStatus'
|
|
type: array
|
|
summary: List all MQTT brokers and their connection status
|
|
tags:
|
|
- Brokers
|
|
/channels:
|
|
get:
|
|
parameters:
|
|
- description: Single-byte channel hash (hex)
|
|
in: query
|
|
name: hash
|
|
type: string
|
|
- description: Filter by IATA code (case-insensitive)
|
|
in: query
|
|
name: iata
|
|
type: string
|
|
- description: last_seen epoch ms of last item for pagination
|
|
in: query
|
|
name: cursor
|
|
type: integer
|
|
- description: Max results (default 50)
|
|
in: query
|
|
name: limit
|
|
type: integer
|
|
produces:
|
|
- application/json
|
|
responses:
|
|
"200":
|
|
description: OK
|
|
schema:
|
|
type: object
|
|
"400":
|
|
description: Bad Request
|
|
schema:
|
|
$ref: '#/definitions/handlers.APIError'
|
|
"500":
|
|
description: Internal Server Error
|
|
schema:
|
|
$ref: '#/definitions/handlers.APIError'
|
|
summary: List channels
|
|
tags:
|
|
- Channels
|
|
/channels/{channelID}:
|
|
get:
|
|
parameters:
|
|
- description: Channel integer ID
|
|
in: path
|
|
name: channelID
|
|
required: true
|
|
type: integer
|
|
produces:
|
|
- application/json
|
|
responses:
|
|
"200":
|
|
description: OK
|
|
schema:
|
|
$ref: '#/definitions/api.Channel'
|
|
"400":
|
|
description: Bad Request
|
|
schema:
|
|
$ref: '#/definitions/handlers.APIError'
|
|
"404":
|
|
description: Not Found
|
|
schema:
|
|
$ref: '#/definitions/handlers.APIError'
|
|
summary: Get channel detail
|
|
tags:
|
|
- Channels
|
|
/channels/{channelID}/messages:
|
|
get:
|
|
parameters:
|
|
- description: Channel integer ID
|
|
in: path
|
|
name: channelID
|
|
required: true
|
|
type: integer
|
|
- description: Return messages after this epoch ms
|
|
in: query
|
|
name: since
|
|
type: integer
|
|
- description: Filter by IATA code
|
|
in: query
|
|
name: iata
|
|
type: string
|
|
- description: Message ID of last item for pagination
|
|
in: query
|
|
name: cursor
|
|
type: integer
|
|
- description: Max results (default 50)
|
|
in: query
|
|
name: limit
|
|
type: integer
|
|
produces:
|
|
- application/json
|
|
responses:
|
|
"200":
|
|
description: OK
|
|
schema:
|
|
type: object
|
|
"400":
|
|
description: Bad Request
|
|
schema:
|
|
$ref: '#/definitions/handlers.APIError'
|
|
"500":
|
|
description: Internal Server Error
|
|
schema:
|
|
$ref: '#/definitions/handlers.APIError'
|
|
summary: List messages for a channel
|
|
tags:
|
|
- Channels
|
|
/iatas:
|
|
get:
|
|
produces:
|
|
- application/json
|
|
responses:
|
|
"200":
|
|
description: OK
|
|
schema:
|
|
items:
|
|
$ref: '#/definitions/api.IATA'
|
|
type: array
|
|
"404":
|
|
description: Not Found
|
|
schema:
|
|
$ref: '#/definitions/handlers.APIError'
|
|
summary: List all IATA codes
|
|
tags:
|
|
- IATAs
|
|
/iatas/{iata}:
|
|
get:
|
|
parameters:
|
|
- description: 3-letter IATA code
|
|
in: path
|
|
name: iata
|
|
required: true
|
|
type: string
|
|
produces:
|
|
- application/json
|
|
responses:
|
|
"200":
|
|
description: OK
|
|
schema:
|
|
$ref: '#/definitions/api.IATA'
|
|
"404":
|
|
description: Not Found
|
|
schema:
|
|
$ref: '#/definitions/handlers.APIError'
|
|
summary: Get a single IATA code
|
|
tags:
|
|
- IATAs
|
|
/messages:
|
|
get:
|
|
parameters:
|
|
- description: Filter by channel integer ID (mutually exclusive with channelHash)
|
|
in: query
|
|
name: channelID
|
|
type: integer
|
|
- description: Filter by channel hash byte hex (mutually exclusive with channelID)
|
|
in: query
|
|
name: channelHash
|
|
type: string
|
|
- description: Return messages after this epoch ms
|
|
in: query
|
|
name: since
|
|
type: integer
|
|
- description: Filter by IATA code
|
|
in: query
|
|
name: iata
|
|
type: string
|
|
- description: Message ID of last item for pagination
|
|
in: query
|
|
name: cursor
|
|
type: integer
|
|
- description: Max results (default 50)
|
|
in: query
|
|
name: limit
|
|
type: integer
|
|
produces:
|
|
- application/json
|
|
responses:
|
|
"200":
|
|
description: OK
|
|
schema:
|
|
type: object
|
|
"400":
|
|
description: Bad Request
|
|
schema:
|
|
$ref: '#/definitions/handlers.APIError'
|
|
"500":
|
|
description: Internal Server Error
|
|
schema:
|
|
$ref: '#/definitions/handlers.APIError'
|
|
summary: List channel messages
|
|
tags:
|
|
- Messages
|
|
/nodes:
|
|
get:
|
|
parameters:
|
|
- description: Node type integer (1=companion, 2=repeater, 3=room_server, 4=sensor)
|
|
in: query
|
|
name: type
|
|
type: integer
|
|
- description: Node type name (companion, repeater, room_server, sensor)
|
|
in: query
|
|
name: typeName
|
|
type: string
|
|
- description: Filter by IATA code (case-insensitive)
|
|
in: query
|
|
name: iata
|
|
type: string
|
|
- description: Partial case-insensitive name match
|
|
in: query
|
|
name: name
|
|
type: string
|
|
- description: Exact public key match (hex)
|
|
in: query
|
|
name: pubkey
|
|
type: string
|
|
- description: Filter to nodes with firmware >= 1.14.0
|
|
in: query
|
|
name: supportsMultibytePaths
|
|
type: boolean
|
|
- description: Filter to nodes with firmware >= 1.11.0
|
|
in: query
|
|
name: supportsMultibyteTraces
|
|
type: boolean
|
|
- description: last_seen epoch ms of last item for pagination
|
|
in: query
|
|
name: cursor
|
|
type: integer
|
|
- description: Max results (default 50)
|
|
in: query
|
|
name: limit
|
|
type: integer
|
|
produces:
|
|
- application/json
|
|
responses:
|
|
"200":
|
|
description: OK
|
|
schema:
|
|
type: object
|
|
"500":
|
|
description: Internal Server Error
|
|
schema:
|
|
$ref: '#/definitions/handlers.APIError'
|
|
summary: List nodes
|
|
tags:
|
|
- Nodes
|
|
/nodes/{nodeId}:
|
|
get:
|
|
parameters:
|
|
- description: Node UUID
|
|
in: path
|
|
name: nodeId
|
|
required: true
|
|
type: string
|
|
produces:
|
|
- application/json
|
|
responses:
|
|
"200":
|
|
description: OK
|
|
schema:
|
|
$ref: '#/definitions/api.Node'
|
|
"400":
|
|
description: Bad Request
|
|
schema:
|
|
$ref: '#/definitions/handlers.APIError'
|
|
"404":
|
|
description: Not Found
|
|
schema:
|
|
$ref: '#/definitions/handlers.APIError'
|
|
summary: Get node detail
|
|
tags:
|
|
- Nodes
|
|
/nodes/{nodeId}/observations:
|
|
get:
|
|
parameters:
|
|
- description: Node UUID
|
|
in: path
|
|
name: nodeId
|
|
required: true
|
|
type: string
|
|
- description: Observation ID of last item for pagination
|
|
in: query
|
|
name: cursor
|
|
type: integer
|
|
- description: Max results (default 50)
|
|
in: query
|
|
name: limit
|
|
type: integer
|
|
produces:
|
|
- application/json
|
|
responses:
|
|
"200":
|
|
description: OK
|
|
schema:
|
|
type: object
|
|
"400":
|
|
description: Bad Request
|
|
schema:
|
|
$ref: '#/definitions/handlers.APIError'
|
|
"500":
|
|
description: Internal Server Error
|
|
schema:
|
|
$ref: '#/definitions/handlers.APIError'
|
|
summary: List packet observations originating from a node
|
|
tags:
|
|
- Nodes
|
|
/observers:
|
|
get:
|
|
parameters:
|
|
- description: Filter by IATA code (case-insensitive)
|
|
in: query
|
|
name: iata
|
|
type: string
|
|
- description: Filter by observer type (e.g. meshcoretomqtt, meshcore-ha)
|
|
in: query
|
|
name: type
|
|
type: string
|
|
- description: Filter by broker name
|
|
in: query
|
|
name: broker
|
|
type: string
|
|
- description: Filter by status (online or offline)
|
|
in: query
|
|
name: status
|
|
type: string
|
|
- description: Partial case-insensitive display name match
|
|
in: query
|
|
name: name
|
|
type: string
|
|
- description: last_seen epoch ms of last item for pagination
|
|
in: query
|
|
name: cursor
|
|
type: integer
|
|
- description: Max results (default 50)
|
|
in: query
|
|
name: limit
|
|
type: integer
|
|
produces:
|
|
- application/json
|
|
responses:
|
|
"200":
|
|
description: OK
|
|
schema:
|
|
type: object
|
|
"500":
|
|
description: Internal Server Error
|
|
schema:
|
|
$ref: '#/definitions/handlers.APIError'
|
|
summary: List observers
|
|
tags:
|
|
- Observers
|
|
/observers/{observerId}:
|
|
get:
|
|
parameters:
|
|
- description: Observer UUID
|
|
in: path
|
|
name: observerId
|
|
required: true
|
|
type: string
|
|
produces:
|
|
- application/json
|
|
responses:
|
|
"200":
|
|
description: OK
|
|
schema:
|
|
$ref: '#/definitions/api.Observer'
|
|
"400":
|
|
description: Bad Request
|
|
schema:
|
|
$ref: '#/definitions/handlers.APIError'
|
|
"404":
|
|
description: Not Found
|
|
schema:
|
|
$ref: '#/definitions/handlers.APIError'
|
|
summary: Get observer detail
|
|
tags:
|
|
- Observers
|
|
/observers/{observerId}/adverts:
|
|
get:
|
|
parameters:
|
|
- description: Observer UUID
|
|
in: path
|
|
name: observerId
|
|
required: true
|
|
type: string
|
|
- description: Observation ID of last item for pagination
|
|
in: query
|
|
name: cursor
|
|
type: integer
|
|
- description: Max results (default 50)
|
|
in: query
|
|
name: limit
|
|
type: integer
|
|
produces:
|
|
- application/json
|
|
responses:
|
|
"200":
|
|
description: OK
|
|
schema:
|
|
type: object
|
|
"400":
|
|
description: Bad Request
|
|
schema:
|
|
$ref: '#/definitions/handlers.APIError'
|
|
"500":
|
|
description: Internal Server Error
|
|
schema:
|
|
$ref: '#/definitions/handlers.APIError'
|
|
summary: List advert packets heard by an observer
|
|
tags:
|
|
- Observers
|
|
/observers/{observerId}/telemetry:
|
|
get:
|
|
parameters:
|
|
- description: Observer UUID
|
|
in: path
|
|
name: observerId
|
|
required: true
|
|
type: string
|
|
- description: Duration window e.g. 24h, 48h, 168h (default 24h)
|
|
in: query
|
|
name: range
|
|
type: string
|
|
- description: Return points after this telemetry ID for WS reconnection backfill
|
|
in: query
|
|
name: afterId
|
|
type: integer
|
|
produces:
|
|
- application/json
|
|
responses:
|
|
"200":
|
|
description: OK
|
|
schema:
|
|
$ref: '#/definitions/api.ObserverTelemetry'
|
|
"400":
|
|
description: Bad Request
|
|
schema:
|
|
$ref: '#/definitions/handlers.APIError'
|
|
"500":
|
|
description: Internal Server Error
|
|
schema:
|
|
$ref: '#/definitions/handlers.APIError'
|
|
summary: Get observer telemetry history
|
|
tags:
|
|
- Observers
|
|
/packets:
|
|
get:
|
|
parameters:
|
|
- description: Filter by payload type integer
|
|
in: query
|
|
name: payloadType
|
|
type: integer
|
|
- description: Filter by payload type name (advert, grp_txt, txt_msg, trace,
|
|
anon_req)
|
|
in: query
|
|
name: payloadTypeName
|
|
type: string
|
|
- description: Filter by route type (0=transport_flood, 1=flood, 2=direct, 3=transport_direct)
|
|
in: query
|
|
name: routeType
|
|
type: integer
|
|
- description: Filter by latest observation IATA (case-insensitive)
|
|
in: query
|
|
name: iata
|
|
type: string
|
|
- description: Filter by first_heard_at >= since (epoch ms)
|
|
in: query
|
|
name: since
|
|
type: integer
|
|
- description: Filter by first_heard_at <= until (epoch ms)
|
|
in: query
|
|
name: until
|
|
type: integer
|
|
- description: last_heard_at epoch ms of last item for pagination
|
|
in: query
|
|
name: cursor
|
|
type: integer
|
|
- description: Max results (default 50)
|
|
in: query
|
|
name: limit
|
|
type: integer
|
|
produces:
|
|
- application/json
|
|
responses:
|
|
"200":
|
|
description: OK
|
|
schema:
|
|
type: object
|
|
"500":
|
|
description: Internal Server Error
|
|
schema:
|
|
$ref: '#/definitions/handlers.APIError'
|
|
summary: List packets
|
|
tags:
|
|
- Packets
|
|
/packets/{packetHash}:
|
|
get:
|
|
parameters:
|
|
- description: Packet hash (hex)
|
|
in: path
|
|
name: packetHash
|
|
required: true
|
|
type: string
|
|
produces:
|
|
- application/json
|
|
responses:
|
|
"200":
|
|
description: OK
|
|
schema:
|
|
$ref: '#/definitions/api.Packet'
|
|
"400":
|
|
description: Bad Request
|
|
schema:
|
|
$ref: '#/definitions/handlers.APIError'
|
|
"404":
|
|
description: Not Found
|
|
schema:
|
|
$ref: '#/definitions/handlers.APIError'
|
|
summary: Get full packet detail
|
|
tags:
|
|
- Packets
|
|
/regions:
|
|
get:
|
|
produces:
|
|
- application/json
|
|
responses:
|
|
"200":
|
|
description: OK
|
|
schema:
|
|
items:
|
|
$ref: '#/definitions/api.RegionSummary'
|
|
type: array
|
|
"404":
|
|
description: Not Found
|
|
schema:
|
|
$ref: '#/definitions/handlers.APIError'
|
|
summary: List all regions
|
|
tags:
|
|
- Regions
|
|
/regions/{regionId}:
|
|
get:
|
|
parameters:
|
|
- description: Region ID
|
|
in: path
|
|
name: regionId
|
|
required: true
|
|
type: integer
|
|
produces:
|
|
- application/json
|
|
responses:
|
|
"200":
|
|
description: OK
|
|
schema:
|
|
$ref: '#/definitions/api.Region'
|
|
"400":
|
|
description: Bad Request
|
|
schema:
|
|
$ref: '#/definitions/handlers.APIError'
|
|
"404":
|
|
description: Not Found
|
|
schema:
|
|
$ref: '#/definitions/handlers.APIError'
|
|
summary: Get a single region
|
|
tags:
|
|
- Regions
|
|
/stats/observations:
|
|
get:
|
|
parameters:
|
|
- description: Filter by IATA code (case-insensitive)
|
|
in: query
|
|
name: iata
|
|
type: string
|
|
- description: Start of window epoch ms (default 7 days ago)
|
|
in: query
|
|
name: since
|
|
type: integer
|
|
produces:
|
|
- application/json
|
|
responses:
|
|
"200":
|
|
description: OK
|
|
schema:
|
|
items:
|
|
$ref: '#/definitions/api.ObservationPoint'
|
|
type: array
|
|
"500":
|
|
description: Internal Server Error
|
|
schema:
|
|
$ref: '#/definitions/handlers.APIError'
|
|
summary: Hourly observation time series
|
|
tags:
|
|
- Stats
|
|
/stats/overview:
|
|
get:
|
|
parameters:
|
|
- description: Filter by IATA code (case-insensitive)
|
|
in: query
|
|
name: iata
|
|
type: string
|
|
produces:
|
|
- application/json
|
|
responses:
|
|
"200":
|
|
description: OK
|
|
schema:
|
|
$ref: '#/definitions/api.StatsOverview'
|
|
"500":
|
|
description: Internal Server Error
|
|
schema:
|
|
$ref: '#/definitions/handlers.APIError'
|
|
summary: Network overview stats (last 24h)
|
|
tags:
|
|
- Stats
|
|
/stats/payload-breakdown:
|
|
get:
|
|
parameters:
|
|
- description: Filter by IATA code (case-insensitive)
|
|
in: query
|
|
name: iata
|
|
type: string
|
|
- description: Start of window epoch ms (default last 24h)
|
|
in: query
|
|
name: since
|
|
type: integer
|
|
produces:
|
|
- application/json
|
|
responses:
|
|
"200":
|
|
description: OK
|
|
schema:
|
|
items:
|
|
$ref: '#/definitions/api.PayloadBreakdownItem'
|
|
type: array
|
|
"500":
|
|
description: Internal Server Error
|
|
schema:
|
|
$ref: '#/definitions/handlers.APIError'
|
|
summary: Observation counts by payload type (last 24h by default)
|
|
tags:
|
|
- Stats
|
|
/stats/top-nodes:
|
|
get:
|
|
parameters:
|
|
- description: Filter by IATA code (case-insensitive)
|
|
in: query
|
|
name: iata
|
|
type: string
|
|
- description: Max results (default 10)
|
|
in: query
|
|
name: limit
|
|
type: integer
|
|
produces:
|
|
- application/json
|
|
responses:
|
|
"200":
|
|
description: OK
|
|
schema:
|
|
items:
|
|
$ref: '#/definitions/api.TopNode'
|
|
type: array
|
|
"500":
|
|
description: Internal Server Error
|
|
schema:
|
|
$ref: '#/definitions/handlers.APIError'
|
|
summary: Top N nodes by observation count (from materialized view)
|
|
tags:
|
|
- Stats
|
|
/stats/top-observers:
|
|
get:
|
|
parameters:
|
|
- description: Filter by IATA code (case-insensitive)
|
|
in: query
|
|
name: iata
|
|
type: string
|
|
- description: Start of window epoch ms (default last 24h)
|
|
in: query
|
|
name: since
|
|
type: integer
|
|
- description: Max results (default 10)
|
|
in: query
|
|
name: limit
|
|
type: integer
|
|
produces:
|
|
- application/json
|
|
responses:
|
|
"200":
|
|
description: OK
|
|
schema:
|
|
items:
|
|
$ref: '#/definitions/api.TopObserver'
|
|
type: array
|
|
"500":
|
|
description: Internal Server Error
|
|
schema:
|
|
$ref: '#/definitions/handlers.APIError'
|
|
summary: Top N observers by observation count (last 24h by default)
|
|
tags:
|
|
- Stats
|
|
schemes:
|
|
- http
|
|
- https
|
|
swagger: "2.0"
|
|
tags:
|
|
- description: Airport/location codes that group observers and packets
|
|
name: IATAs
|
|
- description: Super-regions grouping multiple IATAs
|
|
name: Regions
|
|
- description: MeshCore MQTT observers (gateways)
|
|
name: Observers
|
|
- description: MeshCore radio nodes
|
|
name: Nodes
|
|
- description: LoRa packets heard by observers
|
|
name: Packets
|
|
- description: MeshCore group text channels
|
|
name: Channels
|
|
- description: Decrypted channel messages
|
|
name: Messages
|
|
- description: MQTT broker connection status
|
|
name: Brokers
|
|
- description: Network statistics and time series
|
|
name: Stats
|