{"openapi":"3.1.0","info":{"title":"VSXRank public API","version":"1.0.0","summary":"Install counts, daily growth and search positions for VS Code and Open VSX extensions.","description":"Public, read-only access to VSXRank: install and download totals, the last day of movement, search positions and category leaderboards for every extension on the VS Code Marketplace and Open VSX.\n\nNo authentication and no key: every response is the same data the public pages show anyone.\n\n**The full record.** Each extension here reports both total counters, the latest day of movement and a live search position. Behind them sits every day we have read, rank history for every search an extension appears in, the extensions ranked above it, competitors side by side and alerts on any of it. Run the whole dashboard on a live extension at https://vsxrank.com/demo with no signup, or track your own from $9 a month at https://vsxrank.com/pricing.\n\n**Two registries, two different measurements.** Marketplace figures are unique installs. Open VSX figures are downloads, and every update of every version counts again. They are never summed and never compared; each is reported under its own field name and is null on the registry it does not apply to.\n\n**Null is not zero.** A null count means we hold no reading for that day or that registry. Treating it as zero turns a gap in measurement into a claim that nobody installed anything.\n\n**Rate limit.** 60 requests a minute and 300 an hour per IP address. Only successful reads count against it: errors, 429s included, are free. Every response, errors included, reports both windows in the IETF `RateLimit-Policy` and `RateLimit` fields, plus `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset` for the tighter one. Exceeding it returns 429 with `Retry-After` in seconds.\n\n**Errors.** Every failure is JSON, never an HTML page, including an unknown path anywhere under `/api`: an `error` object with a stable `code`, a `message` and a `resolution` that says what to do next.\n\nThe same six operations are available as Model Context Protocol tools at `https://vsxrank.com/mcp`, over one shared implementation, so both surfaces return identical payloads.","license":{"name":"Data licensed for attributed use","url":"https://vsxrank.com/terms"},"contact":{"name":"VSXRank support","url":"https://vsxrank.com/contact"}},"servers":[{"url":"https://vsxrank.com","description":"Production"}],"tags":[{"name":"catalog","description":"Public catalog reads. No authentication."}],"paths":{"/api/v1/extensions":{"get":{"operationId":"searchExtensions","summary":"Search the extension catalog","description":"Find extensions on either registry by display name, publisher or `publisher.name` id. Returns the id the other tools take, with the current install and download counts. Use this whenever you have a name rather than an id.","tags":["catalog"],"parameters":[{"name":"q","in":"query","required":true,"description":"Display name, publisher, or exact `publisher.name` id.","schema":{"type":"string","minLength":1}},{"name":"limit","in":"query","required":false,"description":"Results to return, 1-25. Default 10.","schema":{"type":"integer","minimum":1,"maximum":25}}],"responses":{"200":{"description":"Search the extension catalog","headers":{"RateLimit-Policy":{"schema":{"type":"string"},"description":"The quota policies, as a Structured Field List (draft-ietf-httpapi-ratelimit-headers): one item per window with its quota `q` and window `w` in seconds.","example":"\"minute\";q=60;w=60, \"hour\";q=300;w=3600"},"RateLimit":{"schema":{"type":"string"},"description":"What is left under each policy: the remaining quota `r` and the seconds `t` until that window resets.","example":"\"minute\";r=59;t=60, \"hour\";r=299;t=3600"},"RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in the window with least headroom."},"RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in it."},"RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until it resets."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchResults"}}}},"400":{"description":"A parameter was missing, malformed or out of range.","headers":{"RateLimit-Policy":{"schema":{"type":"string"},"description":"The quota policies, as a Structured Field List (draft-ietf-httpapi-ratelimit-headers): one item per window with its quota `q` and window `w` in seconds.","example":"\"minute\";q=60;w=60, \"hour\";q=300;w=3600"},"RateLimit":{"schema":{"type":"string"},"description":"What is left under each policy: the remaining quota `r` and the seconds `t` until that window resets.","example":"\"minute\";r=59;t=60, \"hour\";r=299;t=3600"},"RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in the window with least headroom."},"RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in it."},"RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until it resets."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded. `Retry-After` says how long to wait.","headers":{"RateLimit-Policy":{"schema":{"type":"string"},"description":"The quota policies, as a Structured Field List (draft-ietf-httpapi-ratelimit-headers): one item per window with its quota `q` and window `w` in seconds.","example":"\"minute\";q=60;w=60, \"hour\";q=300;w=3600"},"RateLimit":{"schema":{"type":"string"},"description":"What is left under each policy: the remaining quota `r` and the seconds `t` until that window resets.","example":"\"minute\";r=59;t=60, \"hour\";r=299;t=3600"},"RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in the window with least headroom."},"RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in it."},"RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until it resets."},"Retry-After":{"schema":{"type":"integer"},"description":"Seconds to wait before retrying: until the exhausted window that frees up last resets."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"The catalog could not be read.","headers":{"RateLimit-Policy":{"schema":{"type":"string"},"description":"The quota policies, as a Structured Field List (draft-ietf-httpapi-ratelimit-headers): one item per window with its quota `q` and window `w` in seconds.","example":"\"minute\";q=60;w=60, \"hour\";q=300;w=3600"},"RateLimit":{"schema":{"type":"string"},"description":"What is left under each policy: the remaining quota `r` and the seconds `t` until that window resets.","example":"\"minute\";r=59;t=60, \"hour\";r=299;t=3600"},"RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in the window with least headroom."},"RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in it."},"RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until it resets."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/extensions/{registry}/{id}":{"get":{"operationId":"getExtension","summary":"Get one extension's public figures","description":"Identity, current install or download count, rating, category standing and release dates for one extension, on both registries when it is published to both. Also reports the last day of movement, one of the searches it ranks for, and how many searches in total we track it on.","tags":["catalog"],"parameters":[{"name":"registry","in":"path","required":true,"description":"`vscode` for the VS Code Marketplace, `openvsx` for Open VSX.","schema":{"type":"string","enum":["vscode","openvsx"]}},{"name":"id","in":"path","required":true,"description":"The `publisher.name` id, e.g. `ms-python.python`.","schema":{"type":"string","minLength":3}}],"responses":{"200":{"description":"Get one extension's public figures","headers":{"RateLimit-Policy":{"schema":{"type":"string"},"description":"The quota policies, as a Structured Field List (draft-ietf-httpapi-ratelimit-headers): one item per window with its quota `q` and window `w` in seconds.","example":"\"minute\";q=60;w=60, \"hour\";q=300;w=3600"},"RateLimit":{"schema":{"type":"string"},"description":"What is left under each policy: the remaining quota `r` and the seconds `t` until that window resets.","example":"\"minute\";r=59;t=60, \"hour\";r=299;t=3600"},"RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in the window with least headroom."},"RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in it."},"RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until it resets."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Extension"}}}},"400":{"description":"A parameter was missing, malformed or out of range.","headers":{"RateLimit-Policy":{"schema":{"type":"string"},"description":"The quota policies, as a Structured Field List (draft-ietf-httpapi-ratelimit-headers): one item per window with its quota `q` and window `w` in seconds.","example":"\"minute\";q=60;w=60, \"hour\";q=300;w=3600"},"RateLimit":{"schema":{"type":"string"},"description":"What is left under each policy: the remaining quota `r` and the seconds `t` until that window resets.","example":"\"minute\";r=59;t=60, \"hour\";r=299;t=3600"},"RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in the window with least headroom."},"RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in it."},"RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until it resets."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such extension or category.","headers":{"RateLimit-Policy":{"schema":{"type":"string"},"description":"The quota policies, as a Structured Field List (draft-ietf-httpapi-ratelimit-headers): one item per window with its quota `q` and window `w` in seconds.","example":"\"minute\";q=60;w=60, \"hour\";q=300;w=3600"},"RateLimit":{"schema":{"type":"string"},"description":"What is left under each policy: the remaining quota `r` and the seconds `t` until that window resets.","example":"\"minute\";r=59;t=60, \"hour\";r=299;t=3600"},"RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in the window with least headroom."},"RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in it."},"RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until it resets."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded. `Retry-After` says how long to wait.","headers":{"RateLimit-Policy":{"schema":{"type":"string"},"description":"The quota policies, as a Structured Field List (draft-ietf-httpapi-ratelimit-headers): one item per window with its quota `q` and window `w` in seconds.","example":"\"minute\";q=60;w=60, \"hour\";q=300;w=3600"},"RateLimit":{"schema":{"type":"string"},"description":"What is left under each policy: the remaining quota `r` and the seconds `t` until that window resets.","example":"\"minute\";r=59;t=60, \"hour\";r=299;t=3600"},"RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in the window with least headroom."},"RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in it."},"RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until it resets."},"Retry-After":{"schema":{"type":"integer"},"description":"Seconds to wait before retrying: until the exhausted window that frees up last resets."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"The catalog could not be read.","headers":{"RateLimit-Policy":{"schema":{"type":"string"},"description":"The quota policies, as a Structured Field List (draft-ietf-httpapi-ratelimit-headers): one item per window with its quota `q` and window `w` in seconds.","example":"\"minute\";q=60;w=60, \"hour\";q=300;w=3600"},"RateLimit":{"schema":{"type":"string"},"description":"What is left under each policy: the remaining quota `r` and the seconds `t` until that window resets.","example":"\"minute\";r=59;t=60, \"hour\";r=299;t=3600"},"RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in the window with least headroom."},"RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in it."},"RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until it resets."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/extensions/{registry}/{id}/installs":{"get":{"operationId":"getExtensionInstalls","summary":"Get installs per day for the last week","description":"New installs (Marketplace) and new downloads (Open VSX) for the most recent day we can close, plus any version released that day. This is the growth figure neither registry publishes: the day-over-day step in the counters we read every night. One day is the public window; the series behind it is a subscriber feature.","tags":["catalog"],"parameters":[{"name":"registry","in":"path","required":true,"description":"`vscode` for the VS Code Marketplace, `openvsx` for Open VSX.","schema":{"type":"string","enum":["vscode","openvsx"]}},{"name":"id","in":"path","required":true,"description":"The `publisher.name` id.","schema":{"type":"string","minLength":3}}],"responses":{"200":{"description":"Get installs per day for the last week","headers":{"RateLimit-Policy":{"schema":{"type":"string"},"description":"The quota policies, as a Structured Field List (draft-ietf-httpapi-ratelimit-headers): one item per window with its quota `q` and window `w` in seconds.","example":"\"minute\";q=60;w=60, \"hour\";q=300;w=3600"},"RateLimit":{"schema":{"type":"string"},"description":"What is left under each policy: the remaining quota `r` and the seconds `t` until that window resets.","example":"\"minute\";r=59;t=60, \"hour\";r=299;t=3600"},"RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in the window with least headroom."},"RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in it."},"RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until it resets."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExtensionInstalls"}}}},"400":{"description":"A parameter was missing, malformed or out of range.","headers":{"RateLimit-Policy":{"schema":{"type":"string"},"description":"The quota policies, as a Structured Field List (draft-ietf-httpapi-ratelimit-headers): one item per window with its quota `q` and window `w` in seconds.","example":"\"minute\";q=60;w=60, \"hour\";q=300;w=3600"},"RateLimit":{"schema":{"type":"string"},"description":"What is left under each policy: the remaining quota `r` and the seconds `t` until that window resets.","example":"\"minute\";r=59;t=60, \"hour\";r=299;t=3600"},"RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in the window with least headroom."},"RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in it."},"RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until it resets."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such extension or category.","headers":{"RateLimit-Policy":{"schema":{"type":"string"},"description":"The quota policies, as a Structured Field List (draft-ietf-httpapi-ratelimit-headers): one item per window with its quota `q` and window `w` in seconds.","example":"\"minute\";q=60;w=60, \"hour\";q=300;w=3600"},"RateLimit":{"schema":{"type":"string"},"description":"What is left under each policy: the remaining quota `r` and the seconds `t` until that window resets.","example":"\"minute\";r=59;t=60, \"hour\";r=299;t=3600"},"RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in the window with least headroom."},"RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in it."},"RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until it resets."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded. `Retry-After` says how long to wait.","headers":{"RateLimit-Policy":{"schema":{"type":"string"},"description":"The quota policies, as a Structured Field List (draft-ietf-httpapi-ratelimit-headers): one item per window with its quota `q` and window `w` in seconds.","example":"\"minute\";q=60;w=60, \"hour\";q=300;w=3600"},"RateLimit":{"schema":{"type":"string"},"description":"What is left under each policy: the remaining quota `r` and the seconds `t` until that window resets.","example":"\"minute\";r=59;t=60, \"hour\";r=299;t=3600"},"RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in the window with least headroom."},"RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in it."},"RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until it resets."},"Retry-After":{"schema":{"type":"integer"},"description":"Seconds to wait before retrying: until the exhausted window that frees up last resets."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"The catalog could not be read.","headers":{"RateLimit-Policy":{"schema":{"type":"string"},"description":"The quota policies, as a Structured Field List (draft-ietf-httpapi-ratelimit-headers): one item per window with its quota `q` and window `w` in seconds.","example":"\"minute\";q=60;w=60, \"hour\";q=300;w=3600"},"RateLimit":{"schema":{"type":"string"},"description":"What is left under each policy: the remaining quota `r` and the seconds `t` until that window resets.","example":"\"minute\";r=59;t=60, \"hour\";r=299;t=3600"},"RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in the window with least headroom."},"RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in it."},"RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until it resets."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/categories":{"get":{"operationId":"listCategories","summary":"List extension categories","description":"Every category the two registries publish, with how many extensions each holds. The slugs are what `get_category_leaderboard` takes.","tags":["catalog"],"responses":{"200":{"description":"List extension categories","headers":{"RateLimit-Policy":{"schema":{"type":"string"},"description":"The quota policies, as a Structured Field List (draft-ietf-httpapi-ratelimit-headers): one item per window with its quota `q` and window `w` in seconds.","example":"\"minute\";q=60;w=60, \"hour\";q=300;w=3600"},"RateLimit":{"schema":{"type":"string"},"description":"What is left under each policy: the remaining quota `r` and the seconds `t` until that window resets.","example":"\"minute\";r=59;t=60, \"hour\";r=299;t=3600"},"RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in the window with least headroom."},"RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in it."},"RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until it resets."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CategoryList"}}}},"400":{"description":"A parameter was missing, malformed or out of range.","headers":{"RateLimit-Policy":{"schema":{"type":"string"},"description":"The quota policies, as a Structured Field List (draft-ietf-httpapi-ratelimit-headers): one item per window with its quota `q` and window `w` in seconds.","example":"\"minute\";q=60;w=60, \"hour\";q=300;w=3600"},"RateLimit":{"schema":{"type":"string"},"description":"What is left under each policy: the remaining quota `r` and the seconds `t` until that window resets.","example":"\"minute\";r=59;t=60, \"hour\";r=299;t=3600"},"RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in the window with least headroom."},"RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in it."},"RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until it resets."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded. `Retry-After` says how long to wait.","headers":{"RateLimit-Policy":{"schema":{"type":"string"},"description":"The quota policies, as a Structured Field List (draft-ietf-httpapi-ratelimit-headers): one item per window with its quota `q` and window `w` in seconds.","example":"\"minute\";q=60;w=60, \"hour\";q=300;w=3600"},"RateLimit":{"schema":{"type":"string"},"description":"What is left under each policy: the remaining quota `r` and the seconds `t` until that window resets.","example":"\"minute\";r=59;t=60, \"hour\";r=299;t=3600"},"RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in the window with least headroom."},"RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in it."},"RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until it resets."},"Retry-After":{"schema":{"type":"integer"},"description":"Seconds to wait before retrying: until the exhausted window that frees up last resets."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"The catalog could not be read.","headers":{"RateLimit-Policy":{"schema":{"type":"string"},"description":"The quota policies, as a Structured Field List (draft-ietf-httpapi-ratelimit-headers): one item per window with its quota `q` and window `w` in seconds.","example":"\"minute\";q=60;w=60, \"hour\";q=300;w=3600"},"RateLimit":{"schema":{"type":"string"},"description":"What is left under each policy: the remaining quota `r` and the seconds `t` until that window resets.","example":"\"minute\";r=59;t=60, \"hour\";r=299;t=3600"},"RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in the window with least headroom."},"RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in it."},"RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until it resets."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/categories/{slug}":{"get":{"operationId":"getCategoryLeaderboard","summary":"Get a category's leaderboard","description":"The leading extensions in one category on one registry, ordered by count, by growth (`movers`) or by publication date (`new`). Use it to answer who leads a category and who is gaining on them. The ordering carries the answer; per-row growth figures are a subscriber feature.","tags":["catalog"],"parameters":[{"name":"slug","in":"path","required":true,"description":"Category slug from `list_categories`, e.g. `ai`.","schema":{"type":"string","minLength":1}},{"name":"registry","in":"query","required":false,"description":"`vscode` for the VS Code Marketplace, `openvsx` for Open VSX.","schema":{"type":"string","enum":["vscode","openvsx"]}},{"name":"sort","in":"query","required":false,"description":"`installs` (default), `movers` for fastest growing, `new` for newest.","schema":{"type":"string","enum":["installs","movers","new"]}},{"name":"limit","in":"query","required":false,"description":"Rows to return, 1-20. Default 10.","schema":{"type":"integer","minimum":1,"maximum":20}}],"responses":{"200":{"description":"Get a category's leaderboard","headers":{"RateLimit-Policy":{"schema":{"type":"string"},"description":"The quota policies, as a Structured Field List (draft-ietf-httpapi-ratelimit-headers): one item per window with its quota `q` and window `w` in seconds.","example":"\"minute\";q=60;w=60, \"hour\";q=300;w=3600"},"RateLimit":{"schema":{"type":"string"},"description":"What is left under each policy: the remaining quota `r` and the seconds `t` until that window resets.","example":"\"minute\";r=59;t=60, \"hour\";r=299;t=3600"},"RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in the window with least headroom."},"RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in it."},"RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until it resets."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CategoryLeaderboard"}}}},"400":{"description":"A parameter was missing, malformed or out of range.","headers":{"RateLimit-Policy":{"schema":{"type":"string"},"description":"The quota policies, as a Structured Field List (draft-ietf-httpapi-ratelimit-headers): one item per window with its quota `q` and window `w` in seconds.","example":"\"minute\";q=60;w=60, \"hour\";q=300;w=3600"},"RateLimit":{"schema":{"type":"string"},"description":"What is left under each policy: the remaining quota `r` and the seconds `t` until that window resets.","example":"\"minute\";r=59;t=60, \"hour\";r=299;t=3600"},"RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in the window with least headroom."},"RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in it."},"RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until it resets."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such extension or category.","headers":{"RateLimit-Policy":{"schema":{"type":"string"},"description":"The quota policies, as a Structured Field List (draft-ietf-httpapi-ratelimit-headers): one item per window with its quota `q` and window `w` in seconds.","example":"\"minute\";q=60;w=60, \"hour\";q=300;w=3600"},"RateLimit":{"schema":{"type":"string"},"description":"What is left under each policy: the remaining quota `r` and the seconds `t` until that window resets.","example":"\"minute\";r=59;t=60, \"hour\";r=299;t=3600"},"RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in the window with least headroom."},"RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in it."},"RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until it resets."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded. `Retry-After` says how long to wait.","headers":{"RateLimit-Policy":{"schema":{"type":"string"},"description":"The quota policies, as a Structured Field List (draft-ietf-httpapi-ratelimit-headers): one item per window with its quota `q` and window `w` in seconds.","example":"\"minute\";q=60;w=60, \"hour\";q=300;w=3600"},"RateLimit":{"schema":{"type":"string"},"description":"What is left under each policy: the remaining quota `r` and the seconds `t` until that window resets.","example":"\"minute\";r=59;t=60, \"hour\";r=299;t=3600"},"RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in the window with least headroom."},"RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in it."},"RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until it resets."},"Retry-After":{"schema":{"type":"integer"},"description":"Seconds to wait before retrying: until the exhausted window that frees up last resets."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"The catalog could not be read.","headers":{"RateLimit-Policy":{"schema":{"type":"string"},"description":"The quota policies, as a Structured Field List (draft-ietf-httpapi-ratelimit-headers): one item per window with its quota `q` and window `w` in seconds.","example":"\"minute\";q=60;w=60, \"hour\";q=300;w=3600"},"RateLimit":{"schema":{"type":"string"},"description":"What is left under each policy: the remaining quota `r` and the seconds `t` until that window resets.","example":"\"minute\";r=59;t=60, \"hour\";r=299;t=3600"},"RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in the window with least headroom."},"RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in it."},"RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until it resets."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/stats":{"get":{"operationId":"getCatalogStats","summary":"Get catalog-wide statistics","description":"How large each registry's catalog is, how many extensions we read every night, how many appeared this week, and when the last crawl finished. Use it for questions about the ecosystem rather than about one extension.","tags":["catalog"],"responses":{"200":{"description":"Get catalog-wide statistics","headers":{"RateLimit-Policy":{"schema":{"type":"string"},"description":"The quota policies, as a Structured Field List (draft-ietf-httpapi-ratelimit-headers): one item per window with its quota `q` and window `w` in seconds.","example":"\"minute\";q=60;w=60, \"hour\";q=300;w=3600"},"RateLimit":{"schema":{"type":"string"},"description":"What is left under each policy: the remaining quota `r` and the seconds `t` until that window resets.","example":"\"minute\";r=59;t=60, \"hour\";r=299;t=3600"},"RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in the window with least headroom."},"RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in it."},"RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until it resets."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CatalogStats"}}}},"400":{"description":"A parameter was missing, malformed or out of range.","headers":{"RateLimit-Policy":{"schema":{"type":"string"},"description":"The quota policies, as a Structured Field List (draft-ietf-httpapi-ratelimit-headers): one item per window with its quota `q` and window `w` in seconds.","example":"\"minute\";q=60;w=60, \"hour\";q=300;w=3600"},"RateLimit":{"schema":{"type":"string"},"description":"What is left under each policy: the remaining quota `r` and the seconds `t` until that window resets.","example":"\"minute\";r=59;t=60, \"hour\";r=299;t=3600"},"RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in the window with least headroom."},"RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in it."},"RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until it resets."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded. `Retry-After` says how long to wait.","headers":{"RateLimit-Policy":{"schema":{"type":"string"},"description":"The quota policies, as a Structured Field List (draft-ietf-httpapi-ratelimit-headers): one item per window with its quota `q` and window `w` in seconds.","example":"\"minute\";q=60;w=60, \"hour\";q=300;w=3600"},"RateLimit":{"schema":{"type":"string"},"description":"What is left under each policy: the remaining quota `r` and the seconds `t` until that window resets.","example":"\"minute\";r=59;t=60, \"hour\";r=299;t=3600"},"RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in the window with least headroom."},"RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in it."},"RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until it resets."},"Retry-After":{"schema":{"type":"integer"},"description":"Seconds to wait before retrying: until the exhausted window that frees up last resets."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"The catalog could not be read.","headers":{"RateLimit-Policy":{"schema":{"type":"string"},"description":"The quota policies, as a Structured Field List (draft-ietf-httpapi-ratelimit-headers): one item per window with its quota `q` and window `w` in seconds.","example":"\"minute\";q=60;w=60, \"hour\";q=300;w=3600"},"RateLimit":{"schema":{"type":"string"},"description":"What is left under each policy: the remaining quota `r` and the seconds `t` until that window resets.","example":"\"minute\";r=59;t=60, \"hour\";r=299;t=3600"},"RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in the window with least headroom."},"RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in it."},"RateLimit-Reset":{"schema":{"type":"integer"},"description":"Seconds until it resets."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"schemas":{"Error":{"type":"object","description":"Every failure under /api uses this shape. `code` is stable and safe to branch on.","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["not_found","invalid_parameter","rate_limited","method_not_allowed","internal_error"],"description":"Machine-readable reason."},"message":{"type":"string","description":"What went wrong, in a sentence."},"resolution":{"type":"string","description":"What to do about it."},"parameter":{"type":"string","description":"The parameter at fault, when one is."}},"required":["code","message","resolution"],"additionalProperties":false}},"required":["error"],"additionalProperties":false},"SearchResults":{"type":"object","properties":{"query":{"type":"string","description":"The query as it was searched, trimmed."},"count":{"type":"integer","description":"Number of results returned."},"results":{"type":"array","description":"One row per `publisher.name` key, with both registries folded into it.","items":{"type":"object","properties":{"id":{"type":"string","description":"The `publisher.name` id, original casing."},"key":{"type":"string","description":"The same id lowercased. This is what `get_extension` and `get_extension_installs` take."},"displayName":{"type":"string","description":"Listing title."},"publisher":{"type":"string","description":"Publisher display name."},"onMarketplace":{"type":"boolean","description":"Published to the VS Code Marketplace."},"onOpenVsx":{"type":"boolean","description":"Published to Open VSX."},"marketplaceInstalls":{"type":["integer","null"],"description":"Unique installs. Null when not listed on the Marketplace."},"openVsxDownloads":{"type":["integer","null"],"description":"Downloads including every update. Null when not listed on Open VSX."},"marketplaceRating":{"type":["number","null"],"description":"Marketplace average rating, 0-5."},"marketplaceRatingCount":{"type":["integer","null"],"description":"How many Marketplace ratings."},"openVsxRating":{"type":["number","null"],"description":"Open VSX average rating, 0-5. Rated by a different audience."},"openVsxRatingCount":{"type":["integer","null"],"description":"How many Open VSX ratings."},"url":{"type":"string","description":"Public VSXRank page."}},"required":["id","key","displayName","publisher","onMarketplace","onOpenVsx","marketplaceInstalls","openVsxDownloads","marketplaceRating","marketplaceRatingCount","openVsxRating","openVsxRatingCount","url"],"additionalProperties":false}},"countsExplained":{"type":"string","description":"Why the install and download figures must not be compared."},"note":{"type":"string","description":"Where the full history and rank tracking for these extensions live."}},"required":["query","count","results","countsExplained","note"],"additionalProperties":false},"Extension":{"type":"object","properties":{"id":{"type":"string","description":"The lowercased `publisher.name` key that was looked up."},"displayName":{"type":"string","description":"Best display name across the registries that list it."},"listedOn":{"type":"array","description":"Registries that publish this extension.","items":{"type":"string","enum":["vscode","openvsx"]}},"listings":{"type":"array","description":"One entry per registry, never merged.","items":{"type":"object","properties":{"registry":{"type":"string","enum":["vscode","openvsx"],"description":"`vscode` for the VS Code Marketplace, `openvsx` for Open VSX."},"id":{"type":"string","description":"The `publisher.name` id as this registry spells it, original casing."},"displayName":{"type":"string","description":"Listing title. On the Marketplace this is the single strongest driver of search position."},"publisher":{"type":"string","description":"Publisher display name."},"description":{"type":"string","description":"The listing's one-line description."},"categories":{"type":"array","items":{"type":"string"},"description":"Registry categories this listing declares."},"tags":{"type":"array","items":{"type":"string"},"description":"Keywords the listing declares."},"version":{"type":["string","null"],"description":"Latest version we have read."},"lastReleasedAt":{"type":["string","null"],"description":"ISO timestamp of the most recent release. Null when the registry reports no update date."},"firstPublishedAt":{"type":["string","null"],"description":"ISO timestamp of first publication, which is what both registries report as the release date."},"delisted":{"type":"boolean","description":"True when the registry no longer lists it."},"installs":{"type":["integer","null"],"description":"Marketplace unique installs. Always null on an Open VSX listing."},"downloads":{"type":["integer","null"],"description":"Open VSX downloads, counting every update. Always null on a Marketplace listing."},"rating":{"type":["number","null"],"description":"Average rating on this registry, 0-5. The two registries' audiences rate independently."},"ratingCount":{"type":["integer","null"],"description":"How many ratings that average rests on."},"url":{"type":"string","description":"Public VSXRank page for this listing."},"categoryRank":{"type":["object","null"],"description":"Strongest category standing on this registry, or null when unranked.","properties":{"category":{"type":"string","description":"Category name."},"rank":{"type":"integer","description":"Position by install count, 1 is first."},"outOf":{"type":"integer","description":"Listings in that category on that registry."}},"required":["category","rank","outOf"],"additionalProperties":false}},"required":["registry","id","displayName","publisher","description","categories","tags","version","lastReleasedAt","firstPublishedAt","delisted","installs","downloads","rating","ratingCount","url","categoryRank"],"additionalProperties":false}},"latestMovement":{"type":["object","null"],"description":"The newest day whose movement can be closed, or null when we hold no pair of readings.","properties":{"day":{"type":"string","description":"ISO day, UTC."},"marketplaceInstalls":{"type":["integer","null"],"description":"Unique installs gained that day. Can be negative: the Marketplace revises counts down."},"openVsxDownloads":{"type":["integer","null"],"description":"Downloads gained that day, updates included."}},"required":["day","marketplaceInstalls","openVsxDownloads"],"additionalProperties":false},"searchPositions":{"type":"object","properties":{"shown":{"type":"array","description":"The strongest search we track on it (1), chosen the way the public page chooses its first row.","items":{"type":"object","properties":{"keyword":{"type":"string","description":"The search term."},"marketplaceRank":{"type":["integer","null"],"description":"Median position in Marketplace search today. Null when it did not surface."},"openVsxRank":{"type":["integer","null"],"description":"Median position in Open VSX search today. Null when it did not surface."},"resultsForSearch":{"type":["integer","null"],"description":"How many listings that search returns in total."}},"required":["keyword","marketplaceRank","openVsxRank","resultsForSearch"],"additionalProperties":false}},"trackedSearches":{"type":"integer","description":"Searches we hold a position for on this extension."},"hidden":{"type":"integer","description":"Further searches we hold a position for, on the dashboard."},"note":{"type":"string","description":"Where the rest of the search data lives."}},"required":["shown","trackedSearches","hidden","note"],"additionalProperties":false},"trackedSince":{"type":"string","description":"Earliest day we hold a reading for, which may predate our own crawl."},"firstPartyCrawlSince":{"type":"string","description":"First day of our own crawl. Anything earlier was reconstructed from public archives."},"asOf":{"type":"string","description":"Day of the newest reading in this answer."},"countsExplained":{"type":"string","description":"Why the install and download figures must not be compared."},"note":{"type":"string","description":"Where the full record for this extension lives."}},"required":["id","displayName","listedOn","listings","latestMovement","searchPositions","trackedSince","firstPartyCrawlSince","asOf","countsExplained","note"],"additionalProperties":false},"ExtensionInstalls":{"type":"object","properties":{"id":{"type":"string","description":"The lowercased `publisher.name` key that was looked up."},"windowDays":{"type":"integer","description":"Days of movement in this answer."},"listedOn":{"type":"array","description":"Registries that publish this extension. A registry absent here is null on every day.","items":{"type":"string","enum":["vscode","openvsx"]}},"days":{"type":"array","description":"The days in the window, oldest first, so this stays one shape whatever the window is. A registry we hold no pair of readings for is null on that day, never zero. Empty when nothing can be closed yet.","items":{"type":"object","properties":{"day":{"type":"string","description":"ISO day, UTC."},"marketplaceInstalls":{"type":["integer","null"],"description":"Unique installs gained that day. Can be negative: the Marketplace revises counts down."},"openVsxDownloads":{"type":["integer","null"],"description":"Downloads gained that day, updates included."}},"required":["day","marketplaceInstalls","openVsxDownloads"],"additionalProperties":false}},"releases":{"type":"array","description":"Versions released inside the window, so the day's numbers can be read against a release. Usually empty, the window being one day; `lastReleasedAt` on a listing is the general answer to when it last shipped.","items":{"type":"object","properties":{"day":{"type":"string","description":"ISO day of the release."},"version":{"type":"string","description":"Version string."},"preRelease":{"type":"boolean","description":"Flagged pre-release by the publisher."}},"required":["day","version","preRelease"],"additionalProperties":false}},"asOf":{"type":"string","description":"Day of the newest reading."},"note":{"type":"string","description":"How far this extension's full record goes back, and where to open it."}},"required":["id","windowDays","listedOn","days","releases","asOf","note"],"additionalProperties":false},"CategoryList":{"type":"object","properties":{"count":{"type":"integer","description":"Number of categories."},"categories":{"type":"array","items":{"type":"object","properties":{"slug":{"type":"string","description":"Pass this to `get_category_leaderboard`."},"name":{"type":"string","description":"Category name as the registries spell it."},"marketplaceExtensions":{"type":"integer","description":"Listings in this category on the VS Code Marketplace."},"openVsxExtensions":{"type":"integer","description":"Listings in this category on Open VSX."},"url":{"type":"string","description":"Public VSXRank board for the category."}},"required":["slug","name","marketplaceExtensions","openVsxExtensions","url"],"additionalProperties":false}}},"required":["count","categories"],"additionalProperties":false},"CategoryLeaderboard":{"type":"object","properties":{"category":{"type":"string","description":"Category name."},"slug":{"type":"string","description":"Category slug."},"registry":{"type":"string","enum":["vscode","openvsx"],"description":"`vscode` for the VS Code Marketplace, `openvsx` for Open VSX."},"sort":{"type":"string","enum":["installs","movers","new"],"description":"How the rows are ordered."},"totalInCategory":{"type":"integer","description":"Listings in the category on this registry, before the row limit."},"rows":{"type":"array","items":{"type":"object","properties":{"rank":{"type":"integer","description":"Position under the chosen sort, 1 is first."},"registry":{"type":"string","enum":["vscode","openvsx"],"description":"`vscode` for the VS Code Marketplace, `openvsx` for Open VSX."},"id":{"type":"string","description":"The `publisher.name` id as this registry spells it, original casing."},"displayName":{"type":"string","description":"Listing title. On the Marketplace this is the single strongest driver of search position."},"publisher":{"type":"string","description":"Publisher display name."},"description":{"type":"string","description":"The listing's one-line description."},"categories":{"type":"array","items":{"type":"string"},"description":"Registry categories this listing declares."},"tags":{"type":"array","items":{"type":"string"},"description":"Keywords the listing declares."},"version":{"type":["string","null"],"description":"Latest version we have read."},"lastReleasedAt":{"type":["string","null"],"description":"ISO timestamp of the most recent release. Null when the registry reports no update date."},"firstPublishedAt":{"type":["string","null"],"description":"ISO timestamp of first publication, which is what both registries report as the release date."},"delisted":{"type":"boolean","description":"True when the registry no longer lists it."},"installs":{"type":["integer","null"],"description":"Marketplace unique installs. Always null on an Open VSX listing."},"downloads":{"type":["integer","null"],"description":"Open VSX downloads, counting every update. Always null on a Marketplace listing."},"rating":{"type":["number","null"],"description":"Average rating on this registry, 0-5. The two registries' audiences rate independently."},"ratingCount":{"type":["integer","null"],"description":"How many ratings that average rests on."},"url":{"type":"string","description":"Public VSXRank page for this listing."}},"required":["rank","registry","id","displayName","publisher","description","categories","tags","version","lastReleasedAt","firstPublishedAt","delisted","installs","downloads","rating","ratingCount","url"],"additionalProperties":false}},"url":{"type":"string","description":"Public VSXRank board for the category."},"countsExplained":{"type":"string","description":"Why the install and download figures must not be compared."},"note":{"type":"string","description":"Where the full board and its growth figures live."}},"required":["category","slug","registry","sort","totalInCategory","rows","url","countsExplained","note"],"additionalProperties":false},"CatalogStats":{"type":"object","properties":{"marketplaceExtensions":{"type":"integer","description":"Live listings on the VS Code Marketplace."},"openVsxExtensions":{"type":"integer","description":"Live listings on Open VSX."},"trackedNightly":{"type":"string","description":"How many extensions the nightly crawl reads, as a rounded label."},"newThisWeek":{"type":"integer","description":"Listings first seen in the last 7 days."},"earliestDay":{"type":"string","description":"Earliest day any chart can start from, reconstructed days included."},"firstPartyCrawlSince":{"type":"string","description":"First day of our own crawl. Days before it were rebuilt from public archives."},"lastCrawl":{"type":"string","description":"When the most recent crawl finished."},"source":{"type":"string","description":"Where the same numbers are published for people."},"provenance":{"type":"string","description":"How to describe the history honestly."}},"required":["marketplaceExtensions","openVsxExtensions","trackedNightly","newThisWeek","earliestDay","firstPartyCrawlSince","lastCrawl","source","provenance"],"additionalProperties":false}}},"externalDocs":{"description":"API and MCP documentation","url":"https://vsxrank.com/docs"}}