{
  "openapi": "3.1.0",
  "info": {
    "title": "AI Pricing Guru Public API",
    "version": "1.0.0",
    "summary": "Free, daily-updated AI model pricing data.",
    "description": "Public JSON endpoint exposing up-to-date per-token pricing for major AI model providers (OpenAI, Anthropic, Google, DeepSeek, xAI, Mistral, Meta, Groq, Cohere, Together, Perplexity, and more). CORS is enabled for all origins. Prices are collected from public provider sources and can change without notice; verify directly with the provider before making purchasing or budgeting decisions. The AI Pricing Guru dataset is provided for informational use. You may use it for personal, editorial, research, educational, and internal business purposes with appropriate attribution to AI Pricing Guru. Commercial redistribution, resale, republishing at scale, inclusion in a competing public dataset/API, or use as the primary data source for a commercial pricing-comparison product requires prior written permission. Contact info@aipricing.guru for dataset permissions, legal requests, corrections, or takedown requests.",
    "license": {
      "name": "AI Pricing Guru Dataset Terms",
      "url": "https://www.aipricing.guru/terms/"
    },
    "contact": {
      "name": "AI Pricing Guru",
      "url": "https://www.aipricing.guru/about/",
      "email": "info@aipricing.guru"
    }
  },
  "servers": [
    {
      "url": "https://www.aipricing.guru",
      "description": "Production"
    }
  ],
  "paths": {
    "/api/pricing.json": {
      "get": {
        "operationId": "getPricing",
        "summary": "Fetch the full pricing dataset.",
        "description": "Returns the complete pricing dataset covering every tracked model. Updated daily via an automated scraper. Cached for 1 hour at the edge. The response includes a disclaimer because provider prices, billing rules, regions, taxes, and discounts can change without notice.",
        "tags": [
          "pricing"
        ],
        "responses": {
          "200": {
            "description": "Pricing dataset",
            "headers": {
              "Access-Control-Allow-Origin": {
                "schema": {
                  "type": "string"
                },
                "description": "Always \"*\"."
              },
              "Cache-Control": {
                "schema": {
                  "type": "string"
                },
                "description": "public, max-age=3600"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PricingDataset"
                }
              }
            }
          }
        }
      }
    },
    "/api/estimate": {
      "get": {
        "operationId": "getEstimatorInfo",
        "summary": "Fetch estimator endpoint metadata.",
        "description": "Returns a short description and example request for the cost estimator API.",
        "tags": [
          "estimator"
        ],
        "responses": {
          "200": {
            "description": "Estimator endpoint metadata",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "estimateModelCost",
        "summary": "Estimate AI API cost for a model and token workload.",
        "description": "Calculates input, cached-input, output, per-call, and total cost using AI Pricing Guru's current pricing dataset. Exact token counts are preferred. If text or words are supplied, token count is estimated and clearly labeled; raw text is not stored in usage logs. Send scenarios to return bounded workload-mix estimates and a combined total. Provider batch discounts are never assumed unless present in canonical pricing data.",
        "tags": [
          "estimator"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EstimateRequest"
              },
              "examples": {
                "exactTokens": {
                  "summary": "Exact token estimate",
                  "value": {
                    "model": "gpt-5.5",
                    "inputTokens": 100000,
                    "outputTokens": 20000,
                    "cachedInputTokens": 0,
                    "calls": 1
                  }
                },
                "cachedPercent": {
                  "summary": "Cached input percentage",
                  "value": {
                    "model": "claude-sonnet-5",
                    "inputTokens": 250000,
                    "outputTokens": 50000,
                    "cachedInputPercent": 60,
                    "calls": 100
                  }
                },
                "batchScenarios": {
                  "summary": "Workload mix with aggregate total",
                  "value": {
                    "model": "gpt-5.5",
                    "scenarios": [
                      { "id": "summaries", "inputTokens": 100000, "outputTokens": 10000, "calls": 100 },
                      { "id": "classification", "inputTokens": 2000, "outputTokens": 200, "calls": 10000 }
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Cost estimate",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EstimateResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request"
          },
          "404": {
            "description": "Unknown model"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "PricingDataset": {
        "type": "object",
        "required": [
          "lastUpdated",
          "models"
        ],
        "properties": {
          "lastUpdated": {
            "type": "string",
            "format": "date-time",
            "description": "ISO-8601 timestamp of last dataset refresh."
          },
          "scrapedAt": {
            "type": "string",
            "format": "date-time"
          },
          "modelCount": {
            "type": "integer",
            "minimum": 0
          },
          "providerCount": {
            "type": "integer",
            "minimum": 0
          },
          "models": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Model"
            }
          },
          "updated": {
            "type": "string",
            "format": "date",
            "description": "Calendar date of the latest dataset refresh."
          },
          "disclaimer": {
            "type": "string",
            "description": "Usage disclaimer: prices are collected from public provider sources and should be verified directly with the provider before purchase or budget decisions."
          }
        }
      },
      "Model": {
        "type": "object",
        "required": [
          "id",
          "name",
          "provider",
          "pricing"
        ],
        "properties": {
          "id": {
            "type": "string",
            "example": "gpt-5.4"
          },
          "name": {
            "type": "string",
            "example": "GPT-5.4"
          },
          "family": {
            "type": "string",
            "example": "GPT-5.4"
          },
          "provider": {
            "type": "string",
            "example": "openai",
            "description": "Provider slug, lowercase."
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "preview",
              "legacy",
              "deprecated"
            ]
          },
          "pricing": {
            "$ref": "#/components/schemas/Pricing"
          }
        }
      },
      "Pricing": {
        "type": "object",
        "description": "All prices in USD per 1 million tokens.",
        "properties": {
          "inputPerM": {
            "type": "number",
            "minimum": 0,
            "example": 2.5
          },
          "cachedInputPerM": {
            "type": "number",
            "minimum": 0,
            "example": 0.25
          },
          "audioInputPerM": {
            "type": "number",
            "minimum": 0,
            "description": "Optional audio-input rate when it differs from inputPerM.",
            "example": 1
          },
          "audioCachedInputPerM": {
            "type": "number",
            "minimum": 0,
            "description": "Optional cached-audio-input rate when it differs from cachedInputPerM.",
            "example": 0.1
          },
          "inputModalities": {
            "type": "array",
            "description": "Modalities covered by inputPerM and cachedInputPerM when separate modality rates exist.",
            "items": { "type": "string", "enum": ["text", "image", "video"] }
          },
          "outputIncludesThinkingTokens": {
            "type": "boolean",
            "description": "True when the provider states that output pricing includes thinking tokens."
          },
          "cacheWritePerM": {
            "type": "number",
            "minimum": 0,
            "description": "Optional provider cache-write rate in USD per 1 million tokens.",
            "example": 6.25
          },
          "longContext": {
            "$ref": "#/components/schemas/LongContextPricing"
          },
          "outputPerM": {
            "type": "number",
            "minimum": 0,
            "example": 15
          }
        }
      },
      "LongContextPricing": {
        "type": "object",
        "description": "Optional rate tier applied when the provider's long-context threshold is exceeded.",
        "properties": {
          "thresholdInputTokens": { "type": "integer", "minimum": 1, "example": 272000 },
          "thresholdInclusive": { "type": "boolean", "description": "True when the long-context rate starts at the threshold; false or omitted when it starts above the threshold." },
          "inputPerM": { "type": "number", "minimum": 0, "example": 10 },
          "cachedInputPerM": { "type": "number", "minimum": 0, "example": 1 },
          "cacheWritePerM": { "type": "number", "minimum": 0, "example": 12.5 },
          "outputPerM": { "type": "number", "minimum": 0, "example": 45 }
        },
        "required": ["thresholdInputTokens", "inputPerM", "outputPerM"]
      },
      "EstimateRequest": {
        "type": "object",
        "properties": {
          "model": {
            "type": "string",
            "description": "Model ID or model name from /api/pricing.json. Required unless every scenario supplies a model.",
            "example": "gpt-5.5"
          },
          "inputTokens": {
            "type": "integer",
            "minimum": 0,
            "description": "Prompt/input token count. Preferred for exact estimates."
          },
          "outputTokens": {
            "type": "integer",
            "minimum": 0,
            "description": "Completion/output token count."
          },
          "cachedInputTokens": {
            "type": "integer",
            "minimum": 0,
            "description": "Input tokens billed at the cached-input rate."
          },
          "cachedInputPercent": {
            "type": "number",
            "minimum": 0,
            "maximum": 100,
            "description": "Alternative to cachedInputTokens. Applied to inputTokens."
          },
          "calls": {
            "type": "integer",
            "minimum": 1,
            "default": 1,
            "description": "Number of calls to multiply the per-call estimate by."
          },
          "batch": {
            "type": "boolean",
            "default": false,
            "description": "Marks an asynchronous provider batch submission. Standard rates are retained unless canonical pricing data contains a provider-specific batch rate."
          },
          "scenarios": {
            "type": "array",
            "minItems": 1,
            "maxItems": 100,
            "description": "Optional workload scenarios. Each object inherits top-level values and can override them. The response includes each estimate and aggregate totals.",
            "items": { "$ref": "#/components/schemas/EstimateScenario" }
          },
          "words": {
            "type": "number",
            "minimum": 0,
            "description": "Optional rough input-token estimate when exact tokens are not available."
          },
          "text": {
            "type": "string",
            "description": "Optional rough input-token estimate from text length. Raw text is not stored."
          }
        }
      },
      "EstimateScenario": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "description": "Optional caller label returned with this scenario." },
          "model": { "type": "string", "description": "Overrides the top-level model." },
          "inputTokens": { "type": "integer", "minimum": 0 },
          "outputTokens": { "type": "integer", "minimum": 0 },
          "cachedInputTokens": { "type": "integer", "minimum": 0 },
          "cachedInputPercent": { "type": "number", "minimum": 0, "maximum": 100 },
          "calls": { "type": "integer", "minimum": 1 },
          "words": { "type": "number", "minimum": 0 }
        }
      },
      "EstimateResponse": {
        "type": "object",
        "required": [
          "ok",
          "model",
          "tokens",
          "ratesPerMillionTokens",
          "cost",
          "estimateMethod"
        ],
        "properties": {
          "ok": {
            "type": "boolean"
          },
          "model": {
            "type": "object",
            "properties": {
              "id": { "type": "string" },
              "name": { "type": "string" },
              "provider": { "type": "string" },
              "status": { "type": "string" },
              "context": { "type": ["integer", "null"] },
              "lastUpdated": { "type": "string", "format": "date-time" }
            }
          },
          "tokens": {
            "type": "object",
            "properties": {
              "input": { "type": "integer" },
              "uncachedInput": { "type": "integer" },
              "cachedInput": { "type": "integer" },
              "output": { "type": "integer" },
              "calls": { "type": "integer" }
            }
          },
          "ratesPerMillionTokens": {
            "type": "object",
            "properties": {
              "input": { "type": "number" },
              "cachedInput": { "type": "number" },
              "output": { "type": "number" },
              "currency": { "type": "string", "example": "USD" }
            }
          },
          "cost": {
            "type": "object",
            "properties": {
              "input": { "type": "number" },
              "cachedInput": { "type": "number" },
              "output": { "type": "number" },
              "perCall": { "type": "number" },
              "total": { "type": "number" },
              "currency": { "type": "string", "example": "USD" }
            }
          },
          "estimateMethod": {
            "type": "string",
            "enum": [
              "exact_tokens",
              "estimated_from_words",
              "estimated_from_text_length"
            ]
          },
          "batch": {
            "type": "object",
            "properties": {
              "requested": { "type": "boolean" },
              "discountApplied": { "type": "boolean" },
              "pricingMode": { "type": "string" },
              "note": { "type": "string" }
            }
          },
          "mode": { "type": "string", "enum": ["batch_scenarios"] },
          "scenarioCount": { "type": "integer", "minimum": 1 },
          "estimates": {
            "type": "array",
            "items": { "type": "object" },
            "description": "Present for a batch-scenarios response."
          },
          "totals": {
            "type": "object",
            "description": "Aggregate tokens and cost for a batch-scenarios response."
          },
          "privacy": {
            "type": "object",
            "properties": {
              "rawTextStored": { "type": "boolean", "const": false }
            }
          },
          "disclaimer": {
            "type": "string"
          }
        }
      }
    }
  }
}
