{
  "openapi": "3.1.0",
  "info": {
    "title": "ByteAsk public status endpoints",
    "version": "1.0.0",
    "summary": "Read-only JSON endpoints served by byteask.ai.",
    "description": "The three unauthenticated, read-only JSON endpoints that byteask.ai serves: a liveness probe, the service status shown in the site footer, and package download counts. This is not the ByteAsk product API. The ByteAsk CLI talks to a private service that is not documented or offered for third-party use. Product documentation is at https://byteask.ai/docs/.",
    "contact": { "name": "ByteAsk support", "email": "support@byteask.ai", "url": "https://byteask.ai/contact" },
    "termsOfService": "https://byteask.ai/terms"
  },
  "servers": [{ "url": "https://byteask.ai" }],
  "externalDocs": { "description": "ByteAsk documentation", "url": "https://byteask.ai/docs/" },
  "tags": [{ "name": "status", "description": "Liveness, service status and package statistics." }],
  "paths": {
    "/api/health": {
      "get": {
        "operationId": "getHealth",
        "tags": ["status"],
        "summary": "Liveness probe",
        "description": "Returns 200 while the byteask.ai edge worker is serving. GET and HEAD are accepted. Never cached.",
        "responses": {
          "200": {
            "description": "The site is up.",
            "headers": { "Cache-Control": { "description": "Always `no-store`.", "schema": { "type": "string", "const": "no-store" } } },
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Health" }, "example": { "status": "ok" } } }
          },
          "405": { "$ref": "#/components/responses/MethodNotAllowed" }
        }
      }
    },
    "/api/status": {
      "get": {
        "operationId": "getServiceStatus",
        "tags": ["status"],
        "summary": "Service status",
        "description": "The aggregate state of the ByteAsk services as published on status.byteask.ai, read server-side. Cached for 60 seconds at the edge. `unknown` is returned, with HTTP 200, when the status feed cannot be read. GET only.",
        "responses": {
          "200": {
            "description": "The current state.",
            "headers": { "Cache-Control": { "description": "`public, max-age=60`.", "schema": { "type": "string" } } },
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Status" }, "example": { "state": "operational", "fetched_at": "2026-10-28T12:00:00.000Z" } } }
          },
          "405": { "$ref": "#/components/responses/MethodNotAllowed" }
        }
      }
    },
    "/api/stats": {
      "get": {
        "operationId": "getPackageStats",
        "tags": ["status"],
        "summary": "Package download counts",
        "description": "Downloads in the last month of the `byteask` package on PyPI and of `@byteask/cli` on npm, as reported by those registries. Cached for up to one hour at the edge. A count is null when its registry could not be read and no earlier value is held. GET only.",
        "responses": {
          "200": {
            "description": "The counts.",
            "headers": { "Cache-Control": { "description": "`public, max-age=3600` when both counts are fresh, `public, max-age=300` when one is not, `no-store` when neither is known.", "schema": { "type": "string" } } },
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Stats" }, "example": { "pypi_last_month": 1200, "npm_last_month": 800 } } }
          },
          "405": { "$ref": "#/components/responses/MethodNotAllowed" }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Health": {
        "type": "object",
        "required": ["status"],
        "properties": { "status": { "type": "string", "const": "ok" } }
      },
      "Status": {
        "type": "object",
        "required": ["state", "fetched_at"],
        "properties": {
          "state": { "type": "string", "enum": ["operational", "degraded", "partial", "major", "maintenance", "unknown"], "description": "`partial` means some services are down, `major` means all are." },
          "fetched_at": { "type": "string", "format": "date-time" }
        }
      },
      "Stats": {
        "type": "object",
        "required": ["pypi_last_month", "npm_last_month"],
        "properties": {
          "pypi_last_month": { "type": ["integer", "null"], "minimum": 0 },
          "npm_last_month": { "type": ["integer", "null"], "minimum": 0 }
        }
      },
      "Error": {
        "type": "object",
        "required": ["error"],
        "properties": { "error": { "type": "string", "examples": ["method_not_allowed"] } }
      }
    },
    "responses": {
      "MethodNotAllowed": {
        "description": "The method is not supported by this endpoint.",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" }, "example": { "error": "method_not_allowed" } } }
      }
    }
  }
}
