{
 "openapi": "3.1.0",
 "info": {
  "title": "LLM Price Compare API",
  "version": "1.0.0",
  "description": "Open, read-only JSON API for LLM API prices across OpenRouter providers. Data source: OpenRouter (https://openrouter.ai), crawled daily. Token prices are USD per 1M tokens; request/image/web_search are USD per unit. CORS open, no auth. Model arguments accept exact OpenRouter ids (e.g. openai/gpt-4o) or fuzzy names (e.g. gpt, claude opus, deepseek); responses include resolved_id and alternatives."
 },
 "servers": [
  {
   "url": "https://llm-price-compare-b25.pages.dev"
  }
 ],
 "paths": {
  "/api/meta": {
   "get": {
    "summary": "Last crawl time, counts, units",
    "responses": {
     "200": {
      "description": "JSON",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     }
    }
   }
  },
  "/api/models": {
   "get": {
    "summary": "Search / list models (fuzzy)",
    "parameters": [
     {
      "name": "q",
      "in": "query",
      "required": false,
      "description": "Fuzzy query over name/id/vendor",
      "schema": {
       "type": "string"
      },
      "example": "claude opus"
     },
     {
      "name": "vendor",
      "in": "query",
      "required": false,
      "description": "Vendor/author filter, e.g. anthropic",
      "schema": {
       "type": "string"
      },
      "example": "anthropic"
     },
     {
      "name": "limit",
      "in": "query",
      "required": "integer",
      "description": "Max results (default 20, max 500)",
      "schema": {
       "type": 20
      }
     },
     {
      "name": "offset",
      "in": "query",
      "required": "integer",
      "description": "Offset",
      "schema": {
       "type": 0
      }
     }
    ],
    "responses": {
     "200": {
      "description": "JSON",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     }
    }
   }
  },
  "/api/models/{id}": {
   "get": {
    "summary": "One model with every provider's prices (id may contain '/'; fuzzy fallback)",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "description": "OpenRouter id or fuzzy name",
      "schema": {
       "type": "string"
      },
      "example": "deepseek/deepseek-v4.1-flash"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     }
    }
   }
  },
  "/api/compare": {
   "get": {
    "summary": "Side-by-side comparison with cheapest provider per model",
    "parameters": [
     {
      "name": "ids",
      "in": "query",
      "required": true,
      "description": "Comma-separated ids or fuzzy names",
      "schema": {
       "type": "string"
      },
      "example": "gpt,claude opus,deepseek"
     },
     {
      "name": "input",
      "in": "query",
      "required": false,
      "description": "Input tokens (default 1000000; accepts 1e6, 500k, 2m)",
      "schema": {
       "type": "string"
      },
      "example": "1000000"
     },
     {
      "name": "output",
      "in": "query",
      "required": false,
      "description": "Output tokens (default 200000)",
      "schema": {
       "type": "string"
      },
      "example": "200000"
     },
     {
      "name": "cache_hit",
      "in": "query",
      "required": false,
      "description": "Cache hit ratio 0-1 or percent 0-100 (default 0)",
      "schema": {
       "type": "string"
      },
      "example": "0.5"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     }
    }
   }
  },
  "/api/cost": {
   "get": {
    "summary": "Cost estimate per model and provider for a workload",
    "parameters": [
     {
      "name": "ids",
      "in": "query",
      "required": true,
      "description": "Comma-separated ids or fuzzy names",
      "schema": {
       "type": "string"
      },
      "example": "gpt,claude opus"
     },
     {
      "name": "input",
      "in": "query",
      "required": false,
      "description": "Input tokens (default 1000000; accepts 1e6, 500k, 2m)",
      "schema": {
       "type": "string"
      },
      "example": "1000000"
     },
     {
      "name": "output",
      "in": "query",
      "required": false,
      "description": "Output tokens (default 200000)",
      "schema": {
       "type": "string"
      },
      "example": "200000"
     },
     {
      "name": "cache_hit",
      "in": "query",
      "required": false,
      "description": "Cache hit ratio 0-1 or percent 0-100 (default 0)",
      "schema": {
       "type": "string"
      },
      "example": "0.5"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     }
    }
   }
  },
  "/api/rankings": {
   "get": {
    "summary": "OpenRouter popularity rankings (tokens processed)",
    "parameters": [
     {
      "name": "period",
      "in": "query",
      "required": false,
      "description": "week | day | month | trending",
      "schema": {
       "type": "string"
      },
      "example": "week"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     }
    }
   }
  },
  "/api/history/{id}": {
   "get": {
    "summary": "Price change log (old -> new) for a model",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "description": "OpenRouter id or fuzzy name",
      "schema": {
       "type": "string"
      },
      "example": "openai/gpt-4o"
     },
     {
      "name": "limit",
      "in": "query",
      "required": "integer",
      "description": "Max rows (default 200)",
      "schema": {
       "type": 200
      }
     }
    ],
    "responses": {
     "200": {
      "description": "JSON",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     }
    }
   }
  },
  "/api/runs": {
   "get": {
    "summary": "Recent crawl runs with added/changed/removed/unchanged stats",
    "parameters": [
     {
      "name": "limit",
      "in": "query",
      "required": "integer",
      "description": "Max runs (default 20)",
      "schema": {
       "type": 20
      }
     }
    ],
    "responses": {
     "200": {
      "description": "JSON",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     }
    }
   }
  },
  "/api/all": {
   "get": {
    "summary": "Full dataset used by the website (large)",
    "responses": {
     "200": {
      "description": "JSON",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     }
    }
   }
  }
 }
}