{
  "openapi": "3.1.0",
  "info": {
    "title": "Whizi Public Data API",
    "version": "1.0.0",
    "summary": "Public, unauthenticated data endpoints published by whizi.io.",
    "description": "Whizi is a multi-model AI workspace (GPT, Claude, Gemini, Llama, and top image models in one subscription). These endpoints expose the public datasets and machine-readable site indexes that whizi.io publishes for reuse. All of them are static GET endpoints with CORS enabled: no authentication required. The product API used by the Whizi app itself is private and not documented here.\n\nVersioning policy: integrate against the /data/v1/ paths. The v1 dataset schema is stable; fields are only added, never renamed or removed within v1. A breaking change ships as /data/v2/ alongside v1, and v1 then keeps serving for at least 6 months with a Deprecation and Sunset header announcing the retirement date. The unversioned /data/ paths are permanent aliases of the newest version, kept for existing citations. Deprecations are also announced in /llms.txt.\n\nRate limiting: these are static files on a CDN with no per-client quota enforcement. The declared policy is RateLimit-Policy: 1000;w=3600 (stay under 1,000 requests per hour per client and you will never be throttled). No 429 responses are currently issued.\n\nErrors: any request to a path under /api/ on this host returns HTTP 404 with the Error schema as application/json. Nonexistent paths outside /api/ return HTTP 404 with a short HTML body that links the sitemap, /llms.txt, and this spec.",
    "contact": {
      "name": "Whizi",
      "url": "https://whizi.io/support",
      "email": "whizihelp@gmail.com"
    },
    "license": {
      "name": "CC BY 4.0 (applies to the model cost index dataset)",
      "url": "https://creativecommons.org/licenses/by/4.0/"
    }
  },
  "servers": [{ "url": "https://whizi.io" }],
  "paths": {
    "/data/v1/model-cost-index.json": {
      "get": {
        "operationId": "getModelCostIndexJson",
        "summary": "AI model cost index (JSON, v1)",
        "description": "The cost of one standard answer (1,000 input tokens plus 500 output tokens) across 100 models from 29 providers, computed from list prices so rates become comparable. Refreshed with each site deploy. Free to reuse with attribution: \"Whizi AI Model Cost Index, https://whizi.io/tools/model-cost-index\". Also served unversioned at /data/model-cost-index.json.",
        "responses": {
          "200": {
            "description": "The full dataset with methodology, summary statistics, and one entry per model.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ModelCostIndex" }
              }
            }
          },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    },
    "/data/v1/model-cost-index.csv": {
      "get": {
        "operationId": "getModelCostIndexCsv",
        "summary": "AI model cost index (CSV, v1)",
        "description": "The same dataset as /data/v1/model-cost-index.json, flattened to one CSV row per model for spreadsheets. Columns: rank, model, provider, usd_per_1m_input, usd_per_1m_output, context, usd_per_standard_answer, usd_per_1000_answers, whizi_credits_per_message. Also served unversioned at /data/model-cost-index.csv.",
        "responses": {
          "200": {
            "description": "CSV with a header row.",
            "content": { "text/csv": { "schema": { "type": "string" } } }
          },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    },
    "/llms.txt": {
      "get": {
        "operationId": "getLlmsTxt",
        "summary": "Site summary for AI agents (llms.txt)",
        "description": "A curated Markdown index of the site following the llms.txt convention: what Whizi is, pricing, and links to every important page family. Deprecation notices for versioned data endpoints are announced here.",
        "responses": {
          "200": {
            "description": "Markdown as text/plain.",
            "content": { "text/plain": { "schema": { "type": "string" } } }
          },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    },
    "/llms-full.txt": {
      "get": {
        "operationId": "getLlmsFullTxt",
        "summary": "Full site content for AI agents (llms-full.txt)",
        "description": "The expanded llms.txt variant: the direct answer and key facts from every marketing, docs, and comparison page in one plain-text file.",
        "responses": {
          "200": {
            "description": "Markdown as text/plain.",
            "content": { "text/plain": { "schema": { "type": "string" } } }
          },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    },
    "/sitemap.xml": {
      "get": {
        "operationId": "getSitemap",
        "summary": "XML sitemap",
        "description": "Every indexable URL on whizi.io.",
        "responses": {
          "200": {
            "description": "Sitemap XML.",
            "content": { "application/xml": { "schema": { "type": "string" } } }
          },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    }
  },
  "components": {
    "responses": {
      "NotFound": {
        "description": "The path does not exist. Under /api/ the body is the JSON Error object; elsewhere it is a short HTML page linking the sitemap, /llms.txt, and this spec.",
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/Error" }
          }
        }
      }
    },
    "schemas": {
      "ModelCostIndex": {
        "type": "object",
        "description": "The full cost index dataset. Within v1, fields are only added, never renamed or removed.",
        "properties": {
          "name": { "type": "string" },
          "description": { "type": "string" },
          "url": { "type": "string", "format": "uri" },
          "license": { "type": "string", "format": "uri" },
          "attribution": { "type": "string" },
          "methodology": {
            "type": "object",
            "description": "How costPerAnswer is computed: (inPrice * standardInputTokens + outPrice * standardOutputTokens) / 1000000, from OpenRouter list rates."
          },
          "summary": {
            "type": "object",
            "description": "Aggregate statistics: model and provider counts, cheapest and priciest models, spread ratio, price fetch date."
          },
          "models": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/ModelCostEntry" }
          }
        },
        "required": ["name", "url", "license", "models"]
      },
      "ModelCostEntry": {
        "type": "object",
        "description": "One model's pricing, normalized to the standard-answer unit.",
        "properties": {
          "id": { "type": "string", "description": "Stable model identifier (OpenRouter id)." },
          "name": { "type": "string" },
          "provider": { "type": "string" },
          "inPrice": { "type": "number", "description": "USD per 1M input tokens (list price)." },
          "outPrice": { "type": "number", "description": "USD per 1M output tokens (list price)." },
          "context": { "type": "string", "description": "Human-readable context window, e.g. \"200K\"." },
          "contextTokens": { "type": "number" },
          "costPerAnswer": { "type": "number", "description": "USD for one standard answer: 1,000 input tokens plus 500 output tokens." },
          "costPer1kAnswers": { "type": "number" },
          "whiziCredits": { "type": ["number", "null"], "description": "Credits one message spends on Whizi, null if the model is not in the Whizi catalogue." },
          "rank": { "type": "number", "description": "Position when sorted by costPerAnswer, cheapest first." }
        },
        "required": ["id", "name", "provider", "inPrice", "outPrice", "costPerAnswer", "rank"]
      },
      "Error": {
        "type": "object",
        "description": "Structured error returned as application/json by /api/* paths on this host.",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code": { "type": "string", "description": "Machine-readable error code, e.g. \"not_found\"." },
              "message": { "type": "string", "description": "Human-readable description of what went wrong." },
              "status": { "type": "integer", "description": "The HTTP status code, repeated in the body." },
              "hint": { "type": "string", "description": "Where to look next: the spec, /llms.txt, or the docs." }
            },
            "required": ["code", "message", "status"]
          }
        },
        "required": ["error"]
      }
    }
  }
}
