{
  "openapi": "3.1.0",
  "info": {
    "title": "GPUAdvisor Data API",
    "version": "1.0.0",
    "description": "Read-only API for regularly-tracked cloud GPU pricing data. Data reflects the latest manual tracking cycle — not real-time. Confirm current rates before procurement. Free tier requires attribution: 'Data via GPUAdvisor — gpuadvisor.com'.",
    "contact": { "email": "info@gpuadvisor.com", "url": "https://gpuadvisor.com/developers" },
    "license": { "name": "Data terms", "url": "https://gpuadvisor.com/terms" }
  },
  "servers": [{ "url": "https://gpuadvisor.com/api", "description": "Production" }],
  "security": [{ "ApiKeyAuth": [] }],
  "tags": [
    { "name": "catalog",  "description": "GPU models and providers tracked" },
    { "name": "pricing",  "description": "Current and historical per-GPU rates" },
    { "name": "index",    "description": "GPU Price Index series" },
    { "name": "metadata", "description": "API and methodology metadata" }
  ],
  "paths": {
    "/v1/gpus": {
      "get": {
        "tags": ["catalog"],
        "summary": "List tracked GPU models",
        "operationId": "listGpus",
        "responses": {
          "200": { "$ref": "#/components/responses/GpuListResponse" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/providers": {
      "get": {
        "tags": ["catalog"],
        "summary": "List tracked cloud providers",
        "operationId": "listProviders",
        "responses": {
          "200": { "$ref": "#/components/responses/ProviderListResponse" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/prices": {
      "get": {
        "tags": ["pricing"],
        "summary": "Current normalized per-GPU $/hr",
        "description": "Returns on-demand per-GPU-hr rates from the latest (or specified) snapshot. Every record includes pricing_basis_note and snapshot_date.",
        "operationId": "getPrices",
        "parameters": [
          { "name": "gpu",      "in": "query", "schema": { "type": "string" }, "example": "H100 80GB",  "description": "Filter by GPU model" },
          { "name": "provider", "in": "query", "schema": { "type": "string" }, "example": "CoreWeave", "description": "Filter by provider name" },
          { "name": "date",     "in": "query", "schema": { "type": "string", "format": "date" },        "description": "Snapshot date (default: latest)" }
        ],
        "responses": {
          "200": { "$ref": "#/components/responses/PriceResponse" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/history": {
      "get": {
        "tags": ["pricing"],
        "summary": "Per-GPU price history over time",
        "description": "Time-series of on-demand per-GPU-hr rates grouped by provider. Requires 'gpu' param.",
        "operationId": "getHistory",
        "parameters": [
          { "name": "gpu",      "in": "query", "required": true,  "schema": { "type": "string" }, "example": "H100 80GB" },
          { "name": "provider", "in": "query", "required": false, "schema": { "type": "string" }, "example": "AWS" },
          { "name": "from",     "in": "query", "required": false, "schema": { "type": "string", "format": "date" } },
          { "name": "to",       "in": "query", "required": false, "schema": { "type": "string", "format": "date" } }
        ],
        "responses": {
          "200": { "$ref": "#/components/responses/HistoryResponse" },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/index": {
      "get": {
        "tags": ["index"],
        "summary": "GPU Price Index series",
        "description": "Median on-demand per-GPU $/hr per GPU model per snapshot date. Methodology: gpuadvisor.com/gpu-price-index",
        "operationId": "getIndex",
        "parameters": [
          { "name": "gpu_class", "in": "query", "schema": { "type": "string" }, "example": "H100 80GB", "description": "Filter to one GPU model" },
          { "name": "from",      "in": "query", "schema": { "type": "string", "format": "date" } },
          { "name": "to",        "in": "query", "schema": { "type": "string", "format": "date" } }
        ],
        "responses": {
          "200": { "$ref": "#/components/responses/IndexResponse" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/meta": {
      "get": {
        "tags": ["metadata"],
        "summary": "API and methodology metadata",
        "description": "Tracking cadence, provider list, last tracked date, methodology, tier limits.",
        "operationId": "getMeta",
        "responses": {
          "200": { "$ref": "#/components/responses/MetaResponse" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": { "type": "apiKey", "in": "header", "name": "X-API-Key" }
    },
    "schemas": {
      "ResponseMeta": {
        "type": "object",
        "properties": {
          "last_tracked":    { "type": "string", "format": "date", "nullable": true },
          "snapshot_date":   { "type": "string", "format": "date", "nullable": true },
          "pricing_basis":   { "type": "string" },
          "provider_count":  { "type": "integer" },
          "methodology_url": { "type": "string", "format": "uri" },
          "attribution":     { "type": "string", "description": "Required display string for free-tier users." },
          "cadence_note":    { "type": "string" }
        }
      },
      "PriceRecord": {
        "type": "object",
        "properties": {
          "snapshot_date":           { "type": "string", "format": "date" },
          "gpu_model":               { "type": "string" },
          "provider":                { "type": "string" },
          "region":                  { "type": "string" },
          "price_per_gpu_hr":        { "type": "number", "description": "On-demand $/GPU-hr" },
          "spot_per_gpu_hr":         { "type": "number", "nullable": true },
          "reserved1y_per_gpu_hr":   { "type": "number", "nullable": true },
          "reserved3y_per_gpu_hr":   { "type": "number", "nullable": true },
          "pricing_basis_note":      { "type": "string" }
        }
      },
      "IndexPoint": {
        "type": "object",
        "properties": {
          "snapshot_date":           { "type": "string", "format": "date" },
          "median_price_per_gpu_hr": { "type": "number" },
          "min_price_per_gpu_hr":    { "type": "number" },
          "max_price_per_gpu_hr":    { "type": "number" },
          "provider_count":          { "type": "integer" }
        }
      },
      "ErrorResponse": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code":    { "type": "string" },
              "message": { "type": "string" },
              "hint":    { "type": "string", "nullable": true }
            }
          }
        }
      }
    },
    "responses": {
      "GpuListResponse":      { "description": "OK", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "array" }, "meta": { "$ref": "#/components/schemas/ResponseMeta" } } } } } },
      "ProviderListResponse": { "description": "OK", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "array" }, "meta": { "$ref": "#/components/schemas/ResponseMeta" } } } } } },
      "PriceResponse":        { "description": "OK", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/PriceRecord" } }, "meta": { "$ref": "#/components/schemas/ResponseMeta" } } } } } },
      "HistoryResponse":      { "description": "OK", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "array" }, "meta": { "$ref": "#/components/schemas/ResponseMeta" } } } } } },
      "IndexResponse":        { "description": "OK", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "array", "items": { "type": "object", "properties": { "gpu_model": { "type": "string" }, "series": { "type": "array", "items": { "$ref": "#/components/schemas/IndexPoint" } } } } }, "meta": { "$ref": "#/components/schemas/ResponseMeta" } } } } } },
      "MetaResponse":         { "description": "OK", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "object" }, "meta": { "$ref": "#/components/schemas/ResponseMeta" } } } } } },
      "Unauthorized":         { "description": "Missing or invalid API key", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } },
      "BadRequest":           { "description": "Missing required query param",  "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } },
      "NotFound":             { "description": "No matching data",              "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } },
      "RateLimited":          { "description": "Rate limit exceeded",           "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }
    }
  }
}
