{
  "components": {
    "securitySchemes": {
      "BearerAuth": {
        "bearerFormat": "StreamKey",
        "scheme": "bearer",
        "type": "http"
      }
    }
  },
  "info": {
    "contact": {
      "email": "support@pabogate.com",
      "name": "Kestrel Operations"
    },
    "description": "Distributed, high-throughput event ingest service operating across EU edge regions. Fleet: 3 regions.",
    "title": "Kestrel Distributed Event Ingest API",
    "version": "2.4.1"
  },
  "openapi": "3.1.0",
  "paths": {
    "/ingest.v1.IngestService/Stream": {
      "post": {
        "description": "Bidirectional gRPC channel with flow control. Requires HTTP/2 with the gRPC content type; the stream key travels in the authorization metadata rather than an Authorization header.",
        "responses": {
          "200": {
            "description": "Stream closed cleanly (grpc-status OK)"
          },
          "401": {
            "description": "UNAUTHENTICATED - stream key missing or invalid"
          },
          "503": {
            "description": "UNAVAILABLE - node is draining"
          }
        },
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "summary": "Multiplexed gRPC stream"
      }
    },
    "/v1/health": {
      "get": {
        "description": "Returns the legend API version and the serving region.",
        "responses": {
          "200": {
            "description": "Node healthy"
          }
        },
        "summary": "Edge node health"
      }
    },
    "/v1/ingest/push/live-{streamKey}": {
      "post": {
        "description": "Long-lived upload channel for high-throughput batches. The stream key is the final path segment issued with the stream; requests with an unknown key answer like any other miss. The connection is kept alive across successive batches instead of being re-established per request.",
        "parameters": [
          {
            "description": "Opaque per-stream key (UUID format) issued with the stream",
            "in": "path",
            "name": "streamKey",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Payload accepted by the stream worker"
          },
          "404": {
            "description": "No stream with that key"
          },
          "413": {
            "description": "Payload over the request body cap"
          }
        },
        "summary": "Stream push"
      }
    },
    "/v1/streams/live-{streamKey}/ws": {
      "get": {
        "description": "Establishes a persistent bidirectional stream session with the regional edge node. The stream key is the final path segment.",
        "responses": {
          "101": {
            "description": "Switching Protocols to WebSocket"
          },
          "404": {
            "description": "No stream with that key"
          }
        },
        "summary": "Duplex WebSocket streaming"
      }
    },
    "/v1/telemetry/events": {
      "post": {
        "description": "Accepts a JSON event batch up to 64 KiB. Acknowledged at the receiving edge with a per-request batch id.",
        "responses": {
          "202": {
            "description": "Batch accepted and queued"
          },
          "401": {
            "description": "Missing or invalid stream key"
          },
          "405": {
            "description": "Method Not Allowed - POST required"
          },
          "413": {
            "description": "Payload Too Large (over the 64 KiB batch cap)"
          }
        },
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "summary": "Batch event push"
      }
    }
  },
  "servers": [
    {
      "description": "Primary Ingest Node (eu-2)",
      "url": "https://ingest-eu-2.pabogate.com"
    }
  ]
}