{
  "openapi": "3.1.1",
  "info": {
    "title": "LLM Cost Explorer API",
    "version": "1.0.0",
    "summary": "Monthly LLM API cost per model for your workload, with prompt-caching and batch savings.",
    "description": "Every endpoint performs the same calculation as the human page and returns inputs, result, units, assumptions, sources, warnings and computedAt. MCP endpoint: /mcp."
  },
  "servers": [
    {
      "url": "https://llmcostexplorer.usefulweb.site"
    }
  ],
  "paths": {
    "/api/v1/calculate": {
      "post": {
        "operationId": "calculate",
        "summary": "Monthly LLM API cost per model for your workload, with prompt-caching and batch savings.",
        "description": "Calculates what an LLM workload costs per request and per month on each model – requests per day, input and output tokens, the share of the prompt that can be cached, cache hit rate and batch discounts – using live prices from OpenRouter's public models API, a pasted copy of it, or prices you enter. Shows caching and batch savings, the cheapest models that fit your context and budget, and a cost comparison chart.\n\nMethodology:\n- Per request: input cost = uncached tokens × input price + cacheable tokens × (hit rate × cache-read price + (1 − hit rate) × cache-write price); output cost = output tokens × output price. Prices are per 1M tokens.\n- If a model has no cache-read price, caching is not modelled for it (all input at the normal input price). If no cache-write price is listed, misses are charged at the normal input price.\n- Batch: the batch share of requests gets the batch discount on the whole request (as with typical 50 % batch APIs).\n- Monthly = per request × requests/day × days per month (default 30.4). Context check: input + output tokens must fit the context window when it is known.\n- OpenRouter prices come from GET https://openrouter.ai/api/v1/models (pricing.prompt, completion, input_cache_read, input_cache_write in USD per token).",
        "tags": [
          "ai-infra"
        ],
        "x-mcp-tool": "llm_cost_explorer",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LlmCostExplorerInput"
              },
              "examples": {
                "example1": {
                  "summary": "Support bot: 5,000 requests/day, cached system prompt (example prices you entered)",
                  "value": {
                    "priceSource": "manual",
                    "prices": [
                      {
                        "model": "Large model (example)",
                        "inputPerM": 3,
                        "outputPerM": 15,
                        "cacheReadPerM": 0.3,
                        "cacheWritePerM": 3.75,
                        "contextTokens": 200000
                      },
                      {
                        "model": "Mid model (example)",
                        "inputPerM": 0.4,
                        "outputPerM": 1.6,
                        "cacheReadPerM": 0.1,
                        "contextTokens": 1000000
                      },
                      {
                        "model": "Small model (example)",
                        "inputPerM": 0.1,
                        "outputPerM": 0.4,
                        "contextTokens": 8000
                      }
                    ],
                    "requestsPerDay": 5000,
                    "inputTokens": 12000,
                    "outputTokens": 400,
                    "cacheablePct": 75,
                    "cacheHitRate": 90,
                    "budget": 2000
                  }
                },
                "example2": {
                  "summary": "RAG workload on real OpenRouter prices (pasted snapshot 2026-10-14)",
                  "value": {
                    "priceSource": "paste",
                    "modelsJson": "{\"data\":[{\"id\":\"openai/gpt-4o-mini\",\"name\":\"OpenAI: GPT-4o-mini\",\"context_length\":128000,\"architecture\":{\"input_modalities\":[\"text\",\"image\",\"file\"],\"output_modalities\":[\"text\"]},\"pricing\":{\"prompt\":\"0.00000015\",\"completion\":\"0.0000006\",\"input_cache_read\":\"0.000000075\"},\"top_provider\":{\"context_length\":128000,\"max_completion_tokens\":16384},\"supported_parameters\":[\"frequency_penalty\",\"logit_bias\",\"logprobs\",\"max_completion_tokens\",\"max_tokens\",\"prediction\",\"presence_penalty\",\"response_format\",\"seed\",\"stop\",\"structured_outputs\",\"temperature\",\"tool_choice\",\"tools\",\"top_logprobs\",\"top_p\",\"web_search_options\"]},{\"id\":\"google/gemini-2.5-flash\",\"name\":\"Google: Gemini 2.5 Flash\",\"context_length\":1048576,\"architecture\":{\"input_modalities\":[\"file\",\"image\",\"text\",\"audio\",\"video\"],\"output_modalities\":[\"text\"]},\"pricing\":{\"prompt\":\"0.0000003\",\"completion\":\"0.0000025\",\"input_cache_read\":\"0.00000003\",\"input_cache_write\":\"0.0000000833333333333333\"},\"top_provider\":{\"context_length\":1048576,\"max_completion_tokens\":65535},\"supported_parameters\":[\"include_reasoning\",\"max_tokens\",\"reasoning\",\"response_format\",\"seed\",\"stop\",\"structured_outputs\",\"temperature\",\"tool_choice\",\"tools\",\"top_p\"]},{\"id\":\"anthropic/claude-sonnet-4\",\"name\":\"Anthropic: Claude Sonnet 4\",\"context_length\":200000,\"architecture\":{\"input_modalities\":[\"image\",\"text\",\"file\"],\"output_modalities\":[\"text\"]},\"pricing\":{\"prompt\":\"0.000003\",\"completion\":\"0.000015\",\"input_cache_read\":\"0.0000003\",\"input_cache_write\":\"0.00000375\"},\"top_provider\":{\"context_length\":200000,\"max_completion_tokens\":64000},\"supported_parameters\":[\"include_reasoning\",\"max_tokens\",\"reasoning\",\"stop\",\"temperature\",\"tool_choice\",\"tools\",\"top_k\",\"top_p\"]},{\"id\":\"meta-llama/llama-3.3-70b-instruct\",\"name\":\"Meta: Llama 3.3 70B Instruct\",\"context_length\":131072,\"architecture\":{\"input_modalities\":[\"text\"],\"output_modalities\":[\"text\"]},\"pricing\":{\"prompt\":\"0.00000059\",\"completion\":\"0.00000079\",\"input_cache_read\":\"0.000000295\"},\"top_provider\":{\"context_length\":131072,\"max_completion_tokens\":32768},\"supported_parameters\":[\"frequency_penalty\",\"logit_bias\",\"logprobs\",\"max_tokens\",\"min_p\",\"presence_penalty\",\"repetition_penalty\",\"response_format\",\"seed\",\"stop\",\"structured_outputs\",\"temperature\",\"tool_choice\",\"tools\",\"top_k\",\"top_logprobs\",\"top_p\"]},{\"id\":\"deepseek/deepseek-chat-v3.1\",\"name\":\"DeepSeek: DeepSeek V3.1\",\"context_length\":163840,\"architecture\":{\"input_modalities\":[\"text\"],\"output_modalities\":[\"text\"]},\"pricing\":{\"prompt\":\"0.00000025\",\"completion\":\"0.00000095\",\"input_cache_read\":\"0.00000013\"},\"top_provider\":{\"context_length\":163840,\"max_completion_tokens\":32768},\"supported_parameters\":[\"frequency_penalty\",\"include_reasoning\",\"logit_bias\",\"logprobs\",\"max_tokens\",\"min_p\",\"presence_penalty\",\"reasoning\",\"repetition_penalty\",\"response_format\",\"seed\",\"stop\",\"structured_outputs\",\"temperature\",\"tool_choice\",\"tools\",\"top_k\",\"top_logprobs\",\"top_p\"]},{\"id\":\"mistralai/mistral-small-3.2-24b-instruct\",\"name\":\"Mistral: Mistral Small 3.2 24B\",\"context_length\":256000,\"architecture\":{\"input_modalities\":[\"image\",\"text\"],\"output_modalities\":[\"text\"]},\"pricing\":{\"prompt\":\"0.00000009375\",\"completion\":\"0.00000025\"},\"top_provider\":{\"context_length\":256000,\"max_completion_tokens\":16384},\"supported_parameters\":[\"frequency_penalty\",\"logit_bias\",\"logprobs\",\"max_tokens\",\"min_p\",\"presence_penalty\",\"repetition_penalty\",\"response_format\",\"seed\",\"stop\",\"structured_outputs\",\"temperature\",\"tool_choice\",\"tools\",\"top_k\",\"top_logprobs\",\"top_p\"]}]}",
                    "requestsPerDay": 2000,
                    "inputTokens": 6000,
                    "outputTokens": 600,
                    "cacheablePct": 50,
                    "cacheHitRate": 70,
                    "batchSharePct": 30,
                    "batchDiscountPct": 50
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LlmCostExplorerResult"
                }
              }
            }
          },
          "400": {
            "description": "Malformed JSON body.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "Invalid input (see errors[]).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (see Retry-After).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tool": {
      "get": {
        "operationId": "getToolDefinition",
        "summary": "Inputs, output schema and examples for this tool",
        "responses": {
          "200": {
            "description": "Tool definition.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Problem": {
        "type": "object",
        "description": "RFC 9457 problem details. 422 responses include per-field `errors`.",
        "required": [
          "type",
          "title",
          "status",
          "detail"
        ],
        "properties": {
          "type": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": "integer"
          },
          "detail": {
            "type": "string"
          },
          "code": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "field",
                "message"
              ],
              "properties": {
                "field": {
                  "type": "string"
                },
                "message": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "LlmCostExplorerInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "priceSource": {
            "title": "Prices from",
            "type": "string",
            "enum": [
              "manual",
              "openrouter",
              "paste"
            ],
            "default": "manual"
          },
          "prices": {
            "title": "Model prices (USD per 1M tokens)",
            "type": "array",
            "maxItems": 20,
            "items": {
              "type": "object",
              "additionalProperties": false,
              "properties": {
                "model": {
                  "title": "Model",
                  "type": "string",
                  "maxLength": 120
                },
                "inputPerM": {
                  "title": "Input",
                  "type": "number",
                  "minimum": 0
                },
                "outputPerM": {
                  "title": "Output",
                  "type": "number",
                  "minimum": 0
                },
                "cacheReadPerM": {
                  "title": "Cache read",
                  "type": "number",
                  "minimum": 0
                },
                "cacheWritePerM": {
                  "title": "Cache write",
                  "type": "number",
                  "minimum": 0
                },
                "contextTokens": {
                  "title": "Context window",
                  "type": "integer",
                  "minimum": 0
                }
              },
              "required": [
                "model",
                "inputPerM",
                "outputPerM"
              ]
            }
          },
          "modelIds": {
            "title": "OpenRouter model ids",
            "description": "e.g. openai/gpt-4o-mini – one per line. Empty in paste mode = all pasted models.",
            "type": "array",
            "items": {
              "type": "string"
            },
            "maxItems": 20
          },
          "modelsJson": {
            "title": "OpenRouter models JSON",
            "type": "string",
            "maxLength": 3000000
          },
          "requestsPerDay": {
            "title": "Requests per day",
            "type": "number",
            "minimum": 0,
            "maximum": 1000000000,
            "default": 1000
          },
          "inputTokens": {
            "title": "Input tokens per request",
            "type": "integer",
            "minimum": 0,
            "maximum": 10000000,
            "default": 2000,
            "x-unit": "tokens"
          },
          "outputTokens": {
            "title": "Output tokens per request",
            "type": "integer",
            "minimum": 0,
            "maximum": 10000000,
            "default": 500,
            "x-unit": "tokens"
          },
          "cacheablePct": {
            "title": "Cacheable prompt prefix",
            "description": "Share of input tokens that repeat across requests (system prompt, tools, documents).",
            "type": "number",
            "minimum": 0,
            "maximum": 100,
            "default": 0,
            "x-unit": "%"
          },
          "cacheHitRate": {
            "title": "Cache hit rate",
            "type": "number",
            "minimum": 0,
            "maximum": 100,
            "default": 80,
            "x-unit": "%"
          },
          "batchSharePct": {
            "title": "Share of requests sent via batch API",
            "type": "number",
            "minimum": 0,
            "maximum": 100,
            "default": 0,
            "x-unit": "%"
          },
          "batchDiscountPct": {
            "title": "Batch discount",
            "type": "number",
            "minimum": 0,
            "maximum": 100,
            "default": 50,
            "x-unit": "%"
          },
          "daysPerMonth": {
            "title": "Days per month",
            "type": "number",
            "minimum": 1,
            "maximum": 31,
            "default": 30.4
          },
          "budget": {
            "title": "Monthly budget (optional)",
            "type": "number",
            "minimum": 0,
            "x-unit": "USD"
          }
        },
        "required": [
          "requestsPerDay",
          "inputTokens",
          "outputTokens"
        ]
      },
      "LlmCostExplorerResult": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "schemaVersion",
          "tool",
          "computedAt",
          "inputs",
          "summary",
          "result",
          "units",
          "assumptions",
          "sources",
          "warnings",
          "presentation",
          "links"
        ],
        "properties": {
          "schemaVersion": {
            "type": "string",
            "const": "1.0"
          },
          "tool": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "id",
              "name",
              "version"
            ],
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "version": {
                "type": "string"
              }
            }
          },
          "computedAt": {
            "type": "string",
            "format": "date-time"
          },
          "inputs": {
            "type": "object",
            "description": "Normalised inputs actually used, including applied defaults."
          },
          "summary": {
            "type": "string"
          },
          "result": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "currency",
              "requestsPerMonth",
              "lines",
              "cheapest",
              "cheapestWithinConstraints",
              "missing"
            ],
            "properties": {
              "currency": {
                "type": "string",
                "const": "USD"
              },
              "requestsPerMonth": {
                "type": "number"
              },
              "lines": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "model",
                    "inputPerM",
                    "outputPerM",
                    "cacheReadPerM",
                    "cacheWritePerM",
                    "contextTokens",
                    "perRequest",
                    "perThousand",
                    "monthly",
                    "monthlyWithoutCaching",
                    "cachingSavings",
                    "batchSavings",
                    "fitsContext",
                    "withinBudget",
                    "cachingModelled"
                  ],
                  "properties": {
                    "model": {
                      "type": "string"
                    },
                    "inputPerM": {
                      "type": "number"
                    },
                    "outputPerM": {
                      "type": "number"
                    },
                    "cacheReadPerM": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "cacheWritePerM": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "contextTokens": {
                      "type": [
                        "integer",
                        "null"
                      ]
                    },
                    "perRequest": {
                      "type": "number"
                    },
                    "perThousand": {
                      "type": "number"
                    },
                    "monthly": {
                      "type": "number"
                    },
                    "monthlyWithoutCaching": {
                      "type": "number"
                    },
                    "cachingSavings": {
                      "type": "number"
                    },
                    "batchSavings": {
                      "type": "number"
                    },
                    "fitsContext": {
                      "type": [
                        "boolean",
                        "null"
                      ]
                    },
                    "withinBudget": {
                      "type": [
                        "boolean",
                        "null"
                      ]
                    },
                    "cachingModelled": {
                      "type": "boolean"
                    }
                  }
                }
              },
              "cheapest": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "cheapestWithinConstraints": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "missing": {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "description": "Requested OpenRouter ids that were not found."
              }
            }
          },
          "units": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "assumptions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "sources": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "title"
              ],
              "properties": {
                "title": {
                  "type": "string"
                },
                "url": {
                  "type": "string"
                },
                "publisher": {
                  "type": "string"
                },
                "retrievedAt": {
                  "type": "string"
                },
                "note": {
                  "type": "string"
                }
              }
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "presentation": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "Display blocks used by the human page (same data)."
          },
          "links": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "human",
              "api",
              "openapi",
              "methodology"
            ],
            "properties": {
              "human": {
                "type": "string",
                "format": "uri"
              },
              "api": {
                "type": "string",
                "format": "uri"
              },
              "openapi": {
                "type": "string",
                "format": "uri"
              },
              "methodology": {
                "type": "string",
                "format": "uri"
              }
            }
          }
        }
      }
    }
  }
}