{
  "openapi": "3.1.0",
  "info": {
    "title": "UAParse API",
    "version": "0.3.2",
    "summary": "User-Agent parsing plus bot, search crawler, AI crawler and AI agent detection.",
    "description": "Free JSON API behind https://uaparse.mike-tusa.workers.dev. No key needed for light use (about 20 lookups/min per IP; IPv6 per /64; anonymous users share about 10,000 lookups per UTC day). A free API key (by email request: digitalpromohub.support@gmail.com) allows 1,000 lookups per UTC day and about 120 requests/min. Every lookup counts, including result-cache hits. There are no X-RateLimit-* headers; a 429 carries Retry-After. User-Agents are self-reported, so `bot.verified` is always false. AI agents can also use the remote MCP server at https://uaparse.mike-tusa.workers.dev/mcp (see /llms.txt). UAParse is independent and not affiliated with Meta, OpenAI, Google, Anthropic, Amazon, Perplexity or Mistral AI.",
    "contact": {
      "name": "UAParse",
      "email": "digitalpromohub.support@gmail.com",
      "url": "https://uaparse.mike-tusa.workers.dev"
    }
  },
  "servers": [
    {
      "url": "https://uaparse.mike-tusa.workers.dev"
    }
  ],
  "externalDocs": {
    "description": "Human-readable API docs",
    "url": "https://uaparse.mike-tusa.workers.dev/docs"
  },
  "tags": [
    {
      "name": "parse"
    },
    {
      "name": "meta"
    },
    {
      "name": "mcp"
    }
  ],
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "API key (`up_live_` + 64 hex). Optional for /v1/parse and /mcp, required for /v1/bulk. Authorization: Bearer is the only accepted key header."
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "code",
              "message"
            ],
            "properties": {
              "code": {
                "type": "string"
              },
              "message": {
                "type": "string"
              }
            }
          }
        }
      },
      "Bot": {
        "type": "object",
        "required": [
          "is_bot",
          "is_ai_crawler",
          "is_ai_agent",
          "is_search_crawler",
          "category",
          "category_label",
          "name",
          "operator",
          "ai_purpose",
          "ai_agent_kind",
          "robots_token",
          "token_only",
          "info_url",
          "match",
          "verified"
        ],
        "properties": {
          "is_bot": {
            "type": "boolean"
          },
          "is_ai_crawler": {
            "type": "boolean"
          },
          "is_ai_agent": {
            "type": "boolean"
          },
          "is_search_crawler": {
            "type": "boolean"
          },
          "category": {
            "type": [
              "string",
              "null"
            ],
            "description": "ai_crawler, search_crawler, ads_crawler, seo_crawler, social_preview, feed_reader, monitoring, archiver, security_scanner, headless_browser, http_client, other_crawler, unknown_bot"
          },
          "category_label": {
            "type": [
              "string",
              "null"
            ]
          },
          "name": {
            "type": [
              "string",
              "null"
            ]
          },
          "operator": {
            "type": [
              "string",
              "null"
            ]
          },
          "ai_purpose": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "training",
              "search",
              "user_fetch",
              "agent",
              null
            ]
          },
          "ai_agent_kind": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "fetch",
              "browsing",
              null
            ]
          },
          "robots_token": {
            "type": [
              "string",
              "null"
            ]
          },
          "token_only": {
            "type": "boolean"
          },
          "info_url": {
            "type": [
              "string",
              "null"
            ]
          },
          "match": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "list",
              "heuristic",
              null
            ]
          },
          "verified": {
            "type": "boolean",
            "const": false
          }
        }
      },
      "ParseResult": {
        "type": "object",
        "required": [
          "ua",
          "browser",
          "engine",
          "os",
          "device",
          "cpu",
          "is_bot",
          "is_ai_crawler",
          "is_ai_agent",
          "is_search_crawler",
          "bot",
          "list_version",
          "parser"
        ],
        "properties": {
          "ua": {
            "type": "string",
            "maxLength": 2048
          },
          "browser": {
            "type": "object",
            "required": [
              "name",
              "version",
              "major"
            ],
            "properties": {
              "name": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "version": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "major": {
                "type": [
                  "string",
                  "null"
                ]
              }
            }
          },
          "engine": {
            "type": "object",
            "required": [
              "name",
              "version"
            ],
            "properties": {
              "name": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "version": {
                "type": [
                  "string",
                  "null"
                ]
              }
            }
          },
          "os": {
            "type": "object",
            "required": [
              "name",
              "version"
            ],
            "properties": {
              "name": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "version": {
                "type": [
                  "string",
                  "null"
                ]
              }
            }
          },
          "device": {
            "type": "object",
            "required": [
              "type",
              "vendor",
              "model"
            ],
            "properties": {
              "type": {
                "type": "string",
                "enum": [
                  "desktop",
                  "mobile",
                  "tablet",
                  "smarttv",
                  "console",
                  "wearable",
                  "xr",
                  "embedded",
                  "bot",
                  "unknown"
                ]
              },
              "vendor": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "model": {
                "type": [
                  "string",
                  "null"
                ]
              }
            }
          },
          "cpu": {
            "type": "object",
            "required": [
              "architecture"
            ],
            "properties": {
              "architecture": {
                "type": [
                  "string",
                  "null"
                ]
              }
            }
          },
          "is_bot": {
            "type": "boolean"
          },
          "is_ai_crawler": {
            "type": "boolean"
          },
          "is_ai_agent": {
            "type": "boolean"
          },
          "is_search_crawler": {
            "type": "boolean"
          },
          "bot": {
            "$ref": "#/components/schemas/Bot"
          },
          "list_version": {
            "type": "string",
            "examples": [
              "2026-10-08"
            ]
          },
          "parser": {
            "type": "string",
            "examples": [
              "ua-parser-js 1.0.41"
            ]
          }
        }
      },
      "JsonRpcMessage": {
        "type": "object",
        "required": [
          "jsonrpc"
        ],
        "properties": {
          "jsonrpc": {
            "const": "2.0"
          },
          "id": {
            "type": [
              "string",
              "integer"
            ]
          },
          "method": {
            "type": "string"
          },
          "params": {
            "type": "object"
          }
        }
      }
    }
  },
  "paths": {
    "/v1/parse": {
      "get": {
        "tags": [
          "parse"
        ],
        "operationId": "parseGet",
        "summary": "Parse one User-Agent (query string)",
        "security": [
          {},
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "ua",
            "in": "query",
            "required": false,
            "description": "User-Agent to parse (1–2,048 characters, not only spaces). Omit to parse the request's own User-Agent header.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 2048
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Parse result",
            "headers": {
              "x-cache": {
                "description": "`HIT` or `MISS` in the per-isolate result cache (a hit still counts as a lookup)",
                "schema": {
                  "type": "string",
                  "enum": [
                    "HIT",
                    "MISS"
                  ]
                }
              },
              "x-quota-limit": {
                "description": "Keyed requests: the key's daily lookup quota (UTC day)",
                "schema": {
                  "type": "integer"
                }
              },
              "x-quota-remaining": {
                "description": "Keyed requests: lookups left today",
                "schema": {
                  "type": "integer"
                }
              },
              "x-quota-reset": {
                "description": "Keyed requests: when the daily quota resets (next 00:00 UTC, ISO 8601)",
                "schema": {
                  "type": "string",
                  "format": "date-time"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ParseResult"
                }
              }
            }
          },
          "400": {
            "description": "`empty_ua` or `ua_too_long`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "`invalid_api_key`: an Authorization header was sent but the key is unknown or malformed",
            "headers": {
              "WWW-Authenticate": {
                "schema": {
                  "type": "string",
                  "const": "Bearer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "405": {
            "description": "`method_not_allowed`: use GET or POST",
            "headers": {
              "Allow": {
                "schema": {
                  "type": "string",
                  "const": "GET, POST"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "`rate_limited` (per-minute), `quota_exceeded` (the key's daily quota; quota headers included), `daily_capacity_reached` (shared daily capacity) or `too_many_failed_auth` (repeated invalid keys from this IP)",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying",
                "schema": {
                  "type": "integer"
                }
              },
              "x-quota-limit": {
                "description": "Keyed requests: the key's daily lookup quota (UTC day)",
                "schema": {
                  "type": "integer"
                }
              },
              "x-quota-remaining": {
                "description": "Keyed requests: lookups left today",
                "schema": {
                  "type": "integer"
                }
              },
              "x-quota-reset": {
                "description": "Keyed requests: when the daily quota resets (next 00:00 UTC, ISO 8601)",
                "schema": {
                  "type": "string",
                  "format": "date-time"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "`internal_error`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "`keys_unavailable`, `storage_unavailable` or `quota_unavailable` (temporary)",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "parse"
        ],
        "operationId": "parsePost",
        "summary": "Parse one User-Agent (JSON body; recommended)",
        "security": [
          {},
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": false,
          "description": "JSON, at most 8,192 bytes. Omit `ua` (e.g. `{}`) to parse the request's own User-Agent header.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "ua": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 2048
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Parse result",
            "headers": {
              "x-cache": {
                "description": "`HIT` or `MISS` in the per-isolate result cache (a hit still counts as a lookup)",
                "schema": {
                  "type": "string",
                  "enum": [
                    "HIT",
                    "MISS"
                  ]
                }
              },
              "x-quota-limit": {
                "description": "Keyed requests: the key's daily lookup quota (UTC day)",
                "schema": {
                  "type": "integer"
                }
              },
              "x-quota-remaining": {
                "description": "Keyed requests: lookups left today",
                "schema": {
                  "type": "integer"
                }
              },
              "x-quota-reset": {
                "description": "Keyed requests: when the daily quota resets (next 00:00 UTC, ISO 8601)",
                "schema": {
                  "type": "string",
                  "format": "date-time"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ParseResult"
                }
              }
            }
          },
          "400": {
            "description": "`empty_ua`, `ua_too_long`, `invalid_body` (not an object / ua not a string / not UTF-8) or `invalid_json`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "`invalid_api_key`: an Authorization header was sent but the key is unknown or malformed",
            "headers": {
              "WWW-Authenticate": {
                "schema": {
                  "type": "string",
                  "const": "Bearer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "`body_too_large`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "415": {
            "description": "`unsupported_media_type`: send Content-Type: application/json",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "`rate_limited` (per-minute), `quota_exceeded` (the key's daily quota; quota headers included), `daily_capacity_reached` (shared daily capacity) or `too_many_failed_auth` (repeated invalid keys from this IP)",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying",
                "schema": {
                  "type": "integer"
                }
              },
              "x-quota-limit": {
                "description": "Keyed requests: the key's daily lookup quota (UTC day)",
                "schema": {
                  "type": "integer"
                }
              },
              "x-quota-remaining": {
                "description": "Keyed requests: lookups left today",
                "schema": {
                  "type": "integer"
                }
              },
              "x-quota-reset": {
                "description": "Keyed requests: when the daily quota resets (next 00:00 UTC, ISO 8601)",
                "schema": {
                  "type": "string",
                  "format": "date-time"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "`internal_error`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "`keys_unavailable`, `storage_unavailable` or `quota_unavailable` (temporary)",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/bulk": {
      "post": {
        "tags": [
          "parse"
        ],
        "operationId": "parseBulk",
        "summary": "Parse a batch of User-Agents (API key)",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "description": "JSON, at most 65,536 bytes; at most 100 User-Agents (free keys 10). Each UA is one lookup; all-or-nothing.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "uas"
                ],
                "properties": {
                  "uas": {
                    "type": "array",
                    "minItems": 1,
                    "maxItems": 100,
                    "items": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 2048
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Results in input order",
            "headers": {
              "x-quota-limit": {
                "description": "Keyed requests: the key's daily lookup quota (UTC day)",
                "schema": {
                  "type": "integer"
                }
              },
              "x-quota-remaining": {
                "description": "Keyed requests: lookups left today",
                "schema": {
                  "type": "integer"
                }
              },
              "x-quota-reset": {
                "description": "Keyed requests: when the daily quota resets (next 00:00 UTC, ISO 8601)",
                "schema": {
                  "type": "string",
                  "format": "date-time"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "count",
                    "list_version",
                    "results"
                  ],
                  "properties": {
                    "count": {
                      "type": "integer"
                    },
                    "list_version": {
                      "type": "string"
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ParseResult"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "`invalid_body`, `invalid_json`, `empty_batch`, `too_many_uas` or `invalid_ua_item`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "`invalid_api_key` (unknown or malformed key) or `api_key_required` (no key sent)",
            "headers": {
              "WWW-Authenticate": {
                "schema": {
                  "type": "string",
                  "const": "Bearer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "`plan_bulk_limit`: more UAs than the key's plan allows per call",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "405": {
            "description": "`method_not_allowed`: use POST",
            "headers": {
              "Allow": {
                "schema": {
                  "type": "string",
                  "const": "POST"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "`body_too_large`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "415": {
            "description": "`unsupported_media_type`: send Content-Type: application/json",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "`rate_limited` (per-minute), `quota_exceeded` (the key's daily quota; quota headers included), `daily_capacity_reached` (shared daily capacity) or `too_many_failed_auth` (repeated invalid keys from this IP)",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying",
                "schema": {
                  "type": "integer"
                }
              },
              "x-quota-limit": {
                "description": "Keyed requests: the key's daily lookup quota (UTC day)",
                "schema": {
                  "type": "integer"
                }
              },
              "x-quota-remaining": {
                "description": "Keyed requests: lookups left today",
                "schema": {
                  "type": "integer"
                }
              },
              "x-quota-reset": {
                "description": "Keyed requests: when the daily quota resets (next 00:00 UTC, ISO 8601)",
                "schema": {
                  "type": "string",
                  "format": "date-time"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "`internal_error`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "`keys_unavailable`, `storage_unavailable` or `quota_unavailable` (temporary)",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/bots": {
      "get": {
        "tags": [
          "meta"
        ],
        "operationId": "listBots",
        "summary": "The curated bot list (not counted as lookups)",
        "security": [
          {}
        ],
        "responses": {
          "200": {
            "description": "Bot list",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "list_version",
                    "count",
                    "bots"
                  ],
                  "properties": {
                    "list_version": {
                      "type": "string"
                    },
                    "count": {
                      "type": "integer"
                    },
                    "bots": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "name",
                          "category",
                          "operator",
                          "ai_purpose",
                          "is_ai_agent",
                          "ai_agent_kind",
                          "robots_token",
                          "token_only",
                          "info_url",
                          "verified"
                        ],
                        "properties": {
                          "name": {
                            "type": "string"
                          },
                          "category": {
                            "type": "string"
                          },
                          "operator": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "ai_purpose": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "is_ai_agent": {
                            "type": "boolean"
                          },
                          "ai_agent_kind": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "robots_token": {
                            "type": "string"
                          },
                          "token_only": {
                            "type": "boolean"
                          },
                          "info_url": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "verified": {
                            "type": "boolean",
                            "const": false
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "405": {
            "description": "`method_not_allowed`: use GET",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/meta": {
      "get": {
        "tags": [
          "meta"
        ],
        "operationId": "meta",
        "summary": "Version, list version, counts and limits",
        "security": [
          {}
        ],
        "responses": {
          "200": {
            "description": "Metadata",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "service",
                    "version",
                    "build",
                    "list_version",
                    "bot_count",
                    "ai_crawler_count",
                    "ai_agent_count",
                    "parser",
                    "limits"
                  ],
                  "properties": {
                    "service": {
                      "const": "uaparse"
                    },
                    "version": {
                      "type": "string",
                      "examples": [
                        "0.3.2"
                      ]
                    },
                    "build": {
                      "type": "string"
                    },
                    "list_version": {
                      "type": "string"
                    },
                    "bot_count": {
                      "type": "integer"
                    },
                    "ai_crawler_count": {
                      "type": "integer"
                    },
                    "ai_agent_count": {
                      "type": "integer"
                    },
                    "parser": {
                      "type": "string"
                    },
                    "limits": {
                      "type": "object",
                      "required": [
                        "anonymous_per_min",
                        "key_per_min",
                        "batch_max",
                        "max_parse_body_bytes",
                        "max_bulk_body_bytes",
                        "max_ua_length",
                        "plans"
                      ],
                      "properties": {
                        "anonymous_per_min": {
                          "type": "integer"
                        },
                        "key_per_min": {
                          "type": "integer"
                        },
                        "batch_max": {
                          "type": "integer"
                        },
                        "max_parse_body_bytes": {
                          "type": "integer"
                        },
                        "max_bulk_body_bytes": {
                          "type": "integer"
                        },
                        "max_ua_length": {
                          "type": "integer"
                        },
                        "plans": {
                          "type": "object",
                          "additionalProperties": {
                            "type": "object",
                            "properties": {
                              "lookups_per_day": {
                                "type": "integer"
                              },
                              "bulk_max": {
                                "type": "integer"
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "405": {
            "description": "`method_not_allowed`: use GET",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/health": {
      "get": {
        "tags": [
          "meta"
        ],
        "operationId": "health",
        "summary": "Liveness, deployed version and build",
        "security": [
          {}
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "service",
                    "version",
                    "build"
                  ],
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "service": {
                      "const": "uaparse"
                    },
                    "version": {
                      "type": "string",
                      "examples": [
                        "0.3.2"
                      ]
                    },
                    "build": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/mcp": {
      "post": {
        "tags": [
          "mcp"
        ],
        "operationId": "mcp",
        "summary": "Remote MCP server (Streamable HTTP, JSON-RPC 2.0)",
        "description": "Model Context Protocol endpoint. Stateless, JSON responses only (no SSE, no Mcp-Session-Id). Supported protocol versions: 2026-07-28, 2025-11-25, 2025-06-18, 2025-03-26, 2024-11-05. Modern (2026-07-28) requests carry params._meta and the MCP-Protocol-Version, Mcp-Method and Mcp-Name headers; legacy clients use initialize. Tool: parse_user_agent. Same keys and limits as /v1/parse; each tools/call counts as one lookup. Body max 65536 bytes; legacy batches max 10 messages with at most one tools/call.",
        "security": [
          {},
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "MCP-Protocol-Version",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "2026-07-28",
                "2025-11-25",
                "2025-06-18",
                "2025-03-26",
                "2024-11-05"
              ]
            }
          },
          {
            "name": "Mcp-Method",
            "in": "header",
            "required": false,
            "description": "Required for 2026-07-28; must equal the body method",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Mcp-Name",
            "in": "header",
            "required": false,
            "description": "Required for 2026-07-28 tools/call; must equal params.name",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/JsonRpcMessage"
                  },
                  {
                    "type": "array",
                    "maxItems": 10,
                    "items": {
                      "$ref": "#/components/schemas/JsonRpcMessage"
                    }
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "JSON-RPC response (or batch of responses). Tool failures, including rate limits, are results with isError: true (plus Retry-After / X-Quota-* / X-Cache headers from the lookup).",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying",
                "schema": {
                  "type": "integer"
                }
              },
              "x-cache": {
                "description": "`HIT` or `MISS` in the per-isolate result cache (a hit still counts as a lookup)",
                "schema": {
                  "type": "string",
                  "enum": [
                    "HIT",
                    "MISS"
                  ]
                }
              },
              "x-quota-limit": {
                "description": "Keyed requests: the key's daily lookup quota (UTC day)",
                "schema": {
                  "type": "integer"
                }
              },
              "x-quota-remaining": {
                "description": "Keyed requests: lookups left today",
                "schema": {
                  "type": "integer"
                }
              },
              "x-quota-reset": {
                "description": "Keyed requests: when the daily quota resets (next 00:00 UTC, ISO 8601)",
                "schema": {
                  "type": "string",
                  "format": "date-time"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": [
                    "object",
                    "array"
                  ]
                }
              }
            }
          },
          "202": {
            "description": "Notification(s) accepted; no body"
          },
          "400": {
            "description": "Parse error (-32700), invalid request (-32600), header mismatch (-32020), unsupported protocol version (-32022) or missing _meta (-32602)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Invalid API key (JSON-RPC error, data.code = invalid_api_key; no WWW-Authenticate challenge)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "403": {
            "description": "Origin header present but not allowed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "404": {
            "description": "Unknown method in a 2026-07-28 request (-32601)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "413": {
            "description": "Body larger than the cap",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "429": {
            "description": "Too many non-lookup MCP messages from this IP, or too many invalid keys (data.code too_many_failed_auth)",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected internal error (`internal_error`); per-message failures are JSON-RPC -32603 inside a 200 response instead",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Key storage unavailable",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "mcp"
        ],
        "operationId": "mcp_get_not_allowed",
        "summary": "Not supported (stateless server: no SSE stream, no sessions)",
        "responses": {
          "405": {
            "description": "Always 405 with `Allow: POST, OPTIONS` and a JSON-RPC error body",
            "headers": {
              "Allow": {
                "schema": {
                  "type": "string",
                  "const": "POST, OPTIONS"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "mcp"
        ],
        "operationId": "mcp_delete_not_allowed",
        "summary": "Not supported (stateless server: no SSE stream, no sessions)",
        "responses": {
          "405": {
            "description": "Always 405 with `Allow: POST, OPTIONS` and a JSON-RPC error body",
            "headers": {
              "Allow": {
                "schema": {
                  "type": "string",
                  "const": "POST, OPTIONS"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    }
  }
}