{
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "in": "header",
        "name": "X-API-Key",
        "type": "apiKey"
      }
    }
  },
  "info": {
    "description": "MeshCore network analyzer — packet capture, node tracking, and mesh analytics.",
    "license": {
      "name": "MIT"
    },
    "title": "CoreScope API",
    "version": "edge"
  },
  "openapi": "3.0.3",
  "paths": {
    "/api/admin/prune": {
      "post": {
        "description": "Deletes packets and nodes older than the configured retention period.",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "Success"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "summary": "Prune old data",
        "tags": [
          "admin"
        ]
      }
    },
    "/api/analytics/channels": {
      "get": {
        "description": "Message counts and activity per channel.",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "Success"
          }
        },
        "summary": "Channel analytics",
        "tags": [
          "analytics"
        ]
      }
    },
    "/api/analytics/distance": {
      "get": {
        "description": "Geographic distance calculations between nodes.",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "Success"
          }
        },
        "summary": "Distance analytics",
        "tags": [
          "analytics"
        ]
      }
    },
    "/api/analytics/hash-collisions": {
      "get": {
        "description": "Identifies nodes sharing hash prefixes.",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "Success"
          }
        },
        "summary": "Hash collision detection",
        "tags": [
          "analytics"
        ]
      }
    },
    "/api/analytics/hash-sizes": {
      "get": {
        "description": "Distribution of hash prefix sizes across the network.",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "Success"
          }
        },
        "summary": "Hash size analysis",
        "tags": [
          "analytics"
        ]
      }
    },
    "/api/analytics/neighbor-graph": {
      "get": {
        "description": "Full neighbor affinity graph for visualization.",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "Success"
          }
        },
        "summary": "Neighbor graph",
        "tags": [
          "analytics"
        ]
      }
    },
    "/api/analytics/rf": {
      "get": {
        "description": "SNR/RSSI distributions and statistics.",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "Success"
          }
        },
        "summary": "RF analytics",
        "tags": [
          "analytics"
        ]
      }
    },
    "/api/analytics/subpath-detail": {
      "get": {
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "Success"
          }
        },
        "summary": "Subpath detail",
        "tags": [
          "analytics"
        ]
      }
    },
    "/api/analytics/subpaths": {
      "get": {
        "description": "Common routing subpaths through the mesh.",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "Success"
          }
        },
        "summary": "Subpath analysis",
        "tags": [
          "analytics"
        ]
      }
    },
    "/api/analytics/subpaths-bulk": {
      "get": {
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "Success"
          }
        },
        "summary": "Bulk subpath analysis",
        "tags": [
          "analytics"
        ]
      }
    },
    "/api/analytics/topology": {
      "get": {
        "description": "Hop-count distribution and route analysis.",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "Success"
          }
        },
        "summary": "Network topology",
        "tags": [
          "analytics"
        ]
      }
    },
    "/api/audio-lab/buckets": {
      "get": {
        "description": "Returns frequency bucket data for audio analysis.",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "Success"
          }
        },
        "summary": "Audio lab frequency buckets",
        "tags": [
          "analytics"
        ]
      }
    },
    "/api/channels": {
      "get": {
        "description": "Returns known mesh channels with message counts.",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "Success"
          }
        },
        "summary": "List channels",
        "tags": [
          "channels"
        ]
      }
    },
    "/api/channels/{hash}/messages": {
      "get": {
        "description": "Returns messages for a specific channel.",
        "parameters": [
          {
            "in": "path",
            "name": "hash",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "Success"
          }
        },
        "summary": "Get channel messages",
        "tags": [
          "channels"
        ]
      }
    },
    "/api/config/cache": {
      "get": {
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "Success"
          }
        },
        "summary": "Get cache configuration",
        "tags": [
          "config"
        ]
      }
    },
    "/api/config/client": {
      "get": {
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "Success"
          }
        },
        "summary": "Get client configuration",
        "tags": [
          "config"
        ]
      }
    },
    "/api/config/geo-filter": {
      "get": {
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "Success"
          }
        },
        "summary": "Get geo-filter configuration",
        "tags": [
          "config"
        ]
      }
    },
    "/api/config/map": {
      "get": {
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "Success"
          }
        },
        "summary": "Get map configuration",
        "tags": [
          "config"
        ]
      }
    },
    "/api/config/regions": {
      "get": {
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "Success"
          }
        },
        "summary": "Get configured regions",
        "tags": [
          "config"
        ]
      }
    },
    "/api/config/theme": {
      "get": {
        "description": "Returns color maps, CSS variables, and theme defaults.",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "Success"
          }
        },
        "summary": "Get theme configuration",
        "tags": [
          "config"
        ]
      }
    },
    "/api/debug/affinity": {
      "get": {
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "Success"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "summary": "Debug neighbor affinity scores",
        "tags": [
          "admin"
        ]
      }
    },
    "/api/decode": {
      "post": {
        "description": "Decodes a hex-encoded packet without storing it.",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "Success"
          }
        },
        "summary": "Decode a raw packet",
        "tags": [
          "packets"
        ]
      }
    },
    "/api/health": {
      "get": {
        "description": "Returns server health, uptime, and memory stats.",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "Success"
          }
        },
        "summary": "Health check",
        "tags": [
          "admin"
        ]
      }
    },
    "/api/iata-coords": {
      "get": {
        "description": "Returns lat/lon for known airport codes (used for observer positioning).",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "Success"
          }
        },
        "summary": "Get IATA airport coordinates",
        "tags": [
          "config"
        ]
      }
    },
    "/api/nodes": {
      "get": {
        "description": "Returns all known mesh nodes with status and metadata.",
        "parameters": [
          {
            "description": "Filter by node role",
            "in": "query",
            "name": "role",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter by status (active/stale/offline)",
            "in": "query",
            "name": "status",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "Success"
          }
        },
        "summary": "List nodes",
        "tags": [
          "nodes"
        ]
      }
    },
    "/api/nodes/bulk-health": {
      "get": {
        "description": "Returns health status for all nodes in one call.",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "Success"
          }
        },
        "summary": "Bulk node health",
        "tags": [
          "nodes"
        ]
      }
    },
    "/api/nodes/network-status": {
      "get": {
        "description": "Returns counts of active, stale, and offline nodes.",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "Success"
          }
        },
        "summary": "Network status summary",
        "tags": [
          "nodes"
        ]
      }
    },
    "/api/nodes/search": {
      "get": {
        "description": "Search nodes by name or public key prefix.",
        "parameters": [
          {
            "description": "Search query",
            "in": "query",
            "name": "q",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "Success"
          }
        },
        "summary": "Search nodes",
        "tags": [
          "nodes"
        ]
      }
    },
    "/api/nodes/{pubkey}": {
      "get": {
        "description": "Returns full detail for a single node by public key.",
        "parameters": [
          {
            "in": "path",
            "name": "pubkey",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "Success"
          }
        },
        "summary": "Get node detail",
        "tags": [
          "nodes"
        ]
      }
    },
    "/api/nodes/{pubkey}/analytics": {
      "get": {
        "description": "Per-node packet counts, timing, and RF stats.",
        "parameters": [
          {
            "in": "path",
            "name": "pubkey",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "Success"
          }
        },
        "summary": "Get node analytics",
        "tags": [
          "nodes"
        ]
      }
    },
    "/api/nodes/{pubkey}/health": {
      "get": {
        "parameters": [
          {
            "in": "path",
            "name": "pubkey",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "Success"
          }
        },
        "summary": "Get node health",
        "tags": [
          "nodes"
        ]
      }
    },
    "/api/nodes/{pubkey}/neighbors": {
      "get": {
        "description": "Returns neighbor nodes with affinity scores.",
        "parameters": [
          {
            "in": "path",
            "name": "pubkey",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "Success"
          }
        },
        "summary": "Get node neighbors",
        "tags": [
          "nodes"
        ]
      }
    },
    "/api/nodes/{pubkey}/paths": {
      "get": {
        "parameters": [
          {
            "in": "path",
            "name": "pubkey",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "Success"
          }
        },
        "summary": "Get node routing paths",
        "tags": [
          "nodes"
        ]
      }
    },
    "/api/observers": {
      "get": {
        "description": "Returns all known packet observers/gateways.",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "Success"
          }
        },
        "summary": "List observers",
        "tags": [
          "observers"
        ]
      }
    },
    "/api/observers/metrics/summary": {
      "get": {
        "description": "Aggregate metrics across all observers.",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "Success"
          }
        },
        "summary": "Observer metrics summary",
        "tags": [
          "observers"
        ]
      }
    },
    "/api/observers/{id}": {
      "get": {
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "Success"
          }
        },
        "summary": "Get observer detail",
        "tags": [
          "observers"
        ]
      }
    },
    "/api/observers/{id}/analytics": {
      "get": {
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "Success"
          }
        },
        "summary": "Get observer analytics",
        "tags": [
          "observers"
        ]
      }
    },
    "/api/observers/{id}/metrics": {
      "get": {
        "description": "Packet rates, uptime, and performance metrics.",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "Success"
          }
        },
        "summary": "Get observer metrics",
        "tags": [
          "observers"
        ]
      }
    },
    "/api/packets": {
      "get": {
        "description": "Returns decoded packets with filtering, sorting, and pagination.",
        "parameters": [
          {
            "description": "Max packets to return",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "type": "integer"
            }
          },
          {
            "description": "Pagination offset",
            "in": "query",
            "name": "offset",
            "required": false,
            "schema": {
              "type": "integer"
            }
          },
          {
            "description": "Sort field",
            "in": "query",
            "name": "sort",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Sort order (asc/desc)",
            "in": "query",
            "name": "order",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter by packet type",
            "in": "query",
            "name": "type",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter by observer ID",
            "in": "query",
            "name": "observer",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Time range filter (e.g. 1h, 24h, 7d)",
            "in": "query",
            "name": "timeRange",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Full-text search",
            "in": "query",
            "name": "search",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Group duplicate packets by hash",
            "in": "query",
            "name": "groupByHash",
            "required": false,
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "Success"
          }
        },
        "summary": "List packets",
        "tags": [
          "packets"
        ]
      },
      "post": {
        "description": "Submit a raw packet for decoding and storage.",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "Success"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "summary": "Ingest a packet",
        "tags": [
          "packets"
        ]
      }
    },
    "/api/packets/observations": {
      "post": {
        "description": "Submit multiple observer sightings for existing packets.",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "Success"
          }
        },
        "summary": "Batch submit observations",
        "tags": [
          "packets"
        ]
      }
    },
    "/api/packets/timestamps": {
      "get": {
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "Success"
          }
        },
        "summary": "Get packet timestamp ranges",
        "tags": [
          "packets"
        ]
      }
    },
    "/api/packets/{id}": {
      "get": {
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "Success"
          }
        },
        "summary": "Get packet detail",
        "tags": [
          "packets"
        ]
      }
    },
    "/api/perf": {
      "get": {
        "description": "Returns per-endpoint request timing and slow query log.",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "Success"
          }
        },
        "summary": "Performance statistics",
        "tags": [
          "admin"
        ]
      }
    },
    "/api/perf/reset": {
      "post": {
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "Success"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "summary": "Reset performance stats",
        "tags": [
          "admin"
        ]
      }
    },
    "/api/resolve-hops": {
      "get": {
        "description": "Resolves hash prefixes in a hop path to node names. Returns affinity scores and best candidates.",
        "parameters": [
          {
            "description": "Comma-separated hop hash prefixes",
            "in": "query",
            "name": "hops",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "Success"
          }
        },
        "summary": "Resolve hop path",
        "tags": [
          "nodes"
        ]
      }
    },
    "/api/stats": {
      "get": {
        "description": "Returns aggregate stats (node counts, packet counts, observer counts). Cached for 10s.",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "Success"
          }
        },
        "summary": "Network statistics",
        "tags": [
          "admin"
        ]
      }
    },
    "/api/traces/{hash}": {
      "get": {
        "description": "Returns all observer sightings for a packet hash.",
        "parameters": [
          {
            "in": "path",
            "name": "hash",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "Success"
          }
        },
        "summary": "Get packet traces",
        "tags": [
          "packets"
        ]
      }
    }
  },
  "tags": [
    {
      "description": "Server administration and diagnostics",
      "name": "admin"
    },
    {
      "description": "Network analytics and statistics",
      "name": "analytics"
    },
    {
      "description": "Mesh channel operations",
      "name": "channels"
    },
    {
      "description": "Server configuration",
      "name": "config"
    },
    {
      "description": "Mesh node operations",
      "name": "nodes"
    },
    {
      "description": "Packet observer/gateway operations",
      "name": "observers"
    },
    {
      "description": "Packet capture and decoding",
      "name": "packets"
    }
  ]
}
