{
  "openapi": "3.1.0",
  "info": {
    "title": "bossplatform.site Analytics API",
    "version": "2.0.0",
    "description": "Query raw visit data with rich Cloudflare metadata. Filter by any field, aggregate with group_by, and paginate results.",
    "contact": {
      "url": "https://boss.sh"
    }
  },
  "servers": [
    {
      "url": "https://bossplatform.site"
    }
  ],
  "paths": {
    "/api/analytics": {
      "get": {
        "operationId": "getAnalytics",
        "summary": "Query visit analytics",
        "description": "Returns raw visits or aggregated counts. All filter parameters accept comma-separated values for IN matching.",
        "parameters": [
          {
            "name": "tenant",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Filter by tenant. Comma-separated for multiple values."
          },
          {
            "name": "path",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Filter by path. Comma-separated for multiple values."
          },
          {
            "name": "country",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Filter by country. Comma-separated for multiple values."
          },
          {
            "name": "city",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Filter by city. Comma-separated for multiple values."
          },
          {
            "name": "continent",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Filter by continent. Comma-separated for multiple values."
          },
          {
            "name": "region",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Filter by region. Comma-separated for multiple values."
          },
          {
            "name": "region_code",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Filter by region_code. Comma-separated for multiple values."
          },
          {
            "name": "timezone",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Filter by timezone. Comma-separated for multiple values."
          },
          {
            "name": "colo",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Filter by colo. Comma-separated for multiple values."
          },
          {
            "name": "asn",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Filter by asn. Comma-separated for multiple values."
          },
          {
            "name": "as_organization",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Filter by as_organization. Comma-separated for multiple values."
          },
          {
            "name": "device_type",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Filter by device_type. Comma-separated for multiple values."
          },
          {
            "name": "http_protocol",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Filter by http_protocol. Comma-separated for multiple values."
          },
          {
            "name": "tls_version",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Filter by tls_version. Comma-separated for multiple values."
          },
          {
            "name": "is_eu",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Filter by is_eu. Comma-separated for multiple values."
          },
          {
            "name": "start",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Start date (inclusive), YYYY-MM-DD"
          },
          {
            "name": "end",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "End date (inclusive), YYYY-MM-DD"
          },
          {
            "name": "group_by",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Comma-separated fields to GROUP BY. Valid: tenant, path, country, city, continent, region, region_code, timezone, colo, asn, as_organization, device_type, http_protocol, tls_version, is_eu"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 10000,
              "default": 200
            },
            "description": "Max rows (1–10,000)"
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            },
            "description": "Rows to skip"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "const": true
                    },
                    "count": {
                      "type": "integer"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "oneOf": [
                          {
                            "$ref": "#/components/schemas/Visit"
                          },
                          {
                            "$ref": "#/components/schemas/AggregatedRow"
                          }
                        ]
                      }
                    }
                  },
                  "required": [
                    "success",
                    "count",
                    "data"
                  ]
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/schema": {
      "get": {
        "operationId": "getSchema",
        "summary": "Get OpenAPI specification",
        "description": "Returns this OpenAPI 3.1 spec as JSON.",
        "responses": {
          "200": {
            "description": "OpenAPI spec",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Visit": {
        "type": "object",
        "properties": {
          "tenant": {
            "type": "string",
            "example": "brand-a"
          },
          "path": {
            "type": "string",
            "example": "/index.html"
          },
          "country": {
            "type": [
              "string",
              "null"
            ],
            "example": "US"
          },
          "city": {
            "type": [
              "string",
              "null"
            ],
            "example": "Austin"
          },
          "continent": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "AF",
              "AN",
              "AS",
              "EU",
              "NA",
              "OC",
              "SA",
              null
            ],
            "example": "NA"
          },
          "region": {
            "type": [
              "string",
              "null"
            ],
            "example": "Texas"
          },
          "region_code": {
            "type": [
              "string",
              "null"
            ],
            "example": "TX"
          },
          "timezone": {
            "type": [
              "string",
              "null"
            ],
            "example": "America/Chicago"
          },
          "colo": {
            "type": [
              "string",
              "null"
            ],
            "example": "DFW"
          },
          "asn": {
            "type": [
              "integer",
              "null"
            ],
            "example": 395747
          },
          "as_organization": {
            "type": [
              "string",
              "null"
            ],
            "example": "Google Cloud"
          },
          "device_type": {
            "type": "string",
            "enum": [
              "desktop",
              "mobile",
              "tablet",
              "bot",
              "unknown"
            ],
            "example": "desktop"
          },
          "referer": {
            "type": [
              "string",
              "null"
            ],
            "example": "https://google.com"
          },
          "http_protocol": {
            "type": [
              "string",
              "null"
            ],
            "example": "HTTP/2"
          },
          "tls_version": {
            "type": [
              "string",
              "null"
            ],
            "example": "TLSv1.3"
          },
          "is_eu": {
            "type": "integer",
            "enum": [
              0,
              1
            ],
            "example": 0
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "example": "2026-02-11 14:30:00"
          }
        },
        "required": [
          "tenant",
          "path",
          "created_at"
        ]
      },
      "AggregatedRow": {
        "type": "object",
        "description": "Returned when group_by is used. Contains the grouped fields plus a visits count.",
        "properties": {
          "visits": {
            "type": "integer",
            "example": 142
          }
        },
        "additionalProperties": {
          "type": [
            "string",
            "integer",
            "null"
          ]
        },
        "required": [
          "visits"
        ]
      },
      "ErrorResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "const": false
          },
          "error": {
            "type": "string"
          }
        },
        "required": [
          "success",
          "error"
        ]
      }
    }
  }
}