{
  "openapi": "3.1.1",
  "info": {
    "title": "Software Adoption Explorer API",
    "version": "1.0.0",
    "summary": "Open-source usage signals: weekly downloads, growth and version adoption for npm, PyPI, crates.",
    "description": "Every endpoint performs the same calculation as the human page and returns inputs, result, units, assumptions, sources, warnings and computedAt. MCP endpoint: /mcp."
  },
  "servers": [
    {
      "url": "https://softwareadoptionexplorer.usefulweb.site"
    }
  ],
  "paths": {
    "/api/v1/calculate": {
      "post": {
        "operationId": "calculate",
        "summary": "Open-source usage signals: weekly downloads, growth and version adoption for npm, PyPI, crates.",
        "description": "Fetches public download statistics for an npm, PyPI or crates.io package, aggregates them into weekly totals with 4-week growth and long-run change, shows which versions are actually downloaded (npm last week, crates.io last 90 days) and adds dependent counts from deps.dev. Paste saved API JSON to analyse offline.\n\nMethodology:\n- npm: GET https://api.npmjs.org/downloads/range/last-year/<pkg> (daily downloads) and /versions/<pkg>/last-week (downloads per version over the last 7 days).\n- PyPI: GET https://pypistats.org/api/packages/<pkg>/overall?mirrors=false (daily downloads without mirrors, ~180 days) and /recent. pypistats has no per-version endpoint, so version adoption is not available for PyPI.\n- crates.io: GET https://crates.io/api/v1/crates/<name> (metadata, version ids, all-time downloads) and /crates/<name>/downloads (last 90 days per version plus \"extra\" downloads of older versions); the platform fetcher sends an identifying User-Agent, which crates.io requires.\n- Daily values are summed into Monday-start weeks; weeks with fewer than 7 days of data are marked partial and excluded from growth. Growth = last 4 complete weeks vs the 4 before; long-run change = last 4 vs first 4 complete weeks.\n- Version shares = downloads of a version ÷ all version downloads in the same window; majors group 1.x, 2.x … (0.y releases are grouped per minor). \"Highest stable\" is the largest non-prerelease semver.\n- Dependents: deps.dev v3 package lookup → default version → v3alpha …:dependents, i.e. packages in the same ecosystem whose resolved dependency graph contains exactly that version (direct + indirect). Older versions' dependents are not included.\n- Downloads include CI systems, mirrors and bots; they are a usage signal, not a user count.",
        "tags": [
          "public-data"
        ],
        "x-mcp-tool": "software_adoption_explorer",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SoftwareAdoptionExplorerInput"
              },
              "examples": {
                "example1": {
                  "summary": "left-pad on npm, 1 June – 27 September 2026 (pasted API JSON)",
                  "value": {
                    "ecosystem": "npm",
                    "package": "left-pad",
                    "includeDependents": false,
                    "pastedDownloads": "{\"start\":\"2026-06-01\",\"end\":\"2026-09-27\",\"package\":\"left-pad\",\"downloads\":[{\"downloads\":175000,\"day\":\"2026-06-01\"},{\"downloads\":232816,\"day\":\"2026-06-02\"},{\"downloads\":0,\"day\":\"2026-06-03\"},{\"downloads\":194864,\"day\":\"2026-06-04\"},{\"downloads\":216877,\"day\":\"2026-06-05\"},{\"downloads\":143672,\"day\":\"2026-06-06\"},{\"downloads\":185145,\"day\":\"2026-06-07\"},{\"downloads\":239294,\"day\":\"2026-06-08\"},{\"downloads\":230969,\"day\":\"2026-06-09\"},{\"downloads\":234152,\"day\":\"2026-06-10\"},{\"downloads\":221639,\"day\":\"2026-06-11\"},{\"downloads\":211916,\"day\":\"2026-06-12\"},{\"downloads\":119920,\"day\":\"2026-06-13\"},{\"downloads\":85689,\"day\":\"2026-06-14\"},{\"downloads\":203347,\"day\":\"2026-06-15\"},{\"downloads\":216032,\"day\":\"2026-06-16\"},{\"downloads\":238580,\"day\":\"2026-06-17\"},{\"downloads\":227656,\"day\":\"2026-06-18\"},{\"downloads\":199703,\"day\":\"2026-06-19\"},{\"downloads\":158151,\"day\":\"2026-06-20\"},{\"downloads\":145207,\"day\":\"2026-06-21\"},{\"downloads\":213758,\"day\":\"2026-06-22\"},{\"downloads\":217567,\"day\":\"2026-06-23\"},{\"downloads\":207146,\"day\":\"2026-06-24\"},{\"downloads\":198848,\"day\":\"2026-06-25\"},{\"downloads\":198730,\"day\":\"2026-06-26\"},{\"downloads\":122444,\"day\":\"2026-06-27\"},{\"downloads\":129394,\"day\":\"2026-06-28\"},{\"downloads\":208940,\"day\":\"2026-06-29\"},{\"downloads\":227003,\"day\":\"2026-06-30\"},{\"downloads\":199514,\"day\":\"2026-07-01\"},{\"downloads\":201960,\"day\":\"2026-07-02\"},{\"downloads\":158513,\"day\":\"2026-07-03\"},{\"downloads\":95683,\"day\":\"2026-07-04\"},{\"downloads\":91011,\"day\":\"2026-07-05\"},{\"downloads\":213751,\"day\":\"2026-07-06\"},{\"downloads\":223647,\"day\":\"2026-07-07\"},{\"downloads\":218838,\"day\":\"2026-07-08\"},{\"downloads\":206701,\"day\":\"2026-07-09\"},{\"downloads\":188725,\"day\":\"2026-07-10\"},{\"downloads\":112585,\"day\":\"2026-07-11\"},{\"downloads\":0,\"day\":\"2026-07-12\"},{\"downloads\":197758,\"day\":\"2026-07-13\"},{\"downloads\":219483,\"day\":\"2026-07-14\"},{\"downloads\":204443,\"day\":\"2026-07-15\"},{\"downloads\":220701,\"day\":\"2026-07-16\"},{\"downloads\":203782,\"day\":\"2026-07-17\"},{\"downloads\":135474,\"day\":\"2026-07-18\"},{\"downloads\":133764,\"day\":\"2026-07-19\"},{\"downloads\":209041,\"day\":\"2026-07-20\"},{\"downloads\":222618,\"day\":\"2026-07-21\"},{\"downloads\":232408,\"day\":\"2026-07-22\"},{\"downloads\":246014,\"day\":\"2026-07-23\"},{\"downloads\":232139,\"day\":\"2026-07-24\"},{\"downloads\":133414,\"day\":\"2026-07-25\"},{\"downloads\":140608,\"day\":\"2026-07-26\"},{\"downloads\":222134,\"day\":\"2026-07-27\"},{\"downloads\":337501,\"day\":\"2026-07-28\"},{\"downloads\":244182,\"day\":\"2026-07-29\"},{\"downloads\":212975,\"day\":\"2026-07-30\"},{\"downloads\":196545,\"day\":\"2026-07-31\"},{\"downloads\":138423,\"day\":\"2026-08-01\"},{\"downloads\":128097,\"day\":\"2026-08-02\"},{\"downloads\":230019,\"day\":\"2026-08-03\"},{\"downloads\":241200,\"day\":\"2026-08-04\"},{\"downloads\":237078,\"day\":\"2026-08-05\"},{\"downloads\":225288,\"day\":\"2026-08-06\"},{\"downloads\":217107,\"day\":\"2026-08-07\"},{\"downloads\":138038,\"day\":\"2026-08-08\"},{\"downloads\":128615,\"day\":\"2026-08-09\"},{\"downloads\":232606,\"day\":\"2026-08-10\"},{\"downloads\":240670,\"day\":\"2026-08-11\"},{\"downloads\":257056,\"day\":\"2026-08-12\"},{\"downloads\":263563,\"day\":\"2026-08-13\"},{\"downloads\":0,\"day\":\"2026-08-14\"},{\"downloads\":218302,\"day\":\"2026-08-15\"},{\"downloads\":145375,\"day\":\"2026-08-16\"},{\"downloads\":219779,\"day\":\"2026-08-17\"},{\"downloads\":234519,\"day\":\"2026-08-18\"},{\"downloads\":241463,\"day\":\"2026-08-19\"},{\"downloads\":237126,\"day\":\"2026-08-20\"},{\"downloads\":262372,\"day\":\"2026-08-21\"},{\"downloads\":182718,\"day\":\"2026-08-22\"},{\"downloads\":183373,\"day\":\"2026-08-23\"},{\"downloads\":302721,\"day\":\"2026-08-24\"},{\"downloads\":299137,\"day\":\"2026-08-25\"},{\"downloads\":294024,\"day\":\"2026-08-26\"},{\"downloads\":299028,\"day\":\"2026-08-27\"},{\"downloads\":301719,\"day\":\"2026-08-28\"},{\"downloads\":175288,\"day\":\"2026-08-29\"},{\"downloads\":159943,\"day\":\"2026-08-30\"},{\"downloads\":265975,\"day\":\"2026-08-31\"},{\"downloads\":271782,\"day\":\"2026-09-01\"},{\"downloads\":287623,\"day\":\"2026-09-02\"},{\"downloads\":0,\"day\":\"2026-09-03\"},{\"downloads\":236542,\"day\":\"2026-09-04\"},{\"downloads\":163525,\"day\":\"2026-09-05\"},{\"downloads\":211090,\"day\":\"2026-09-06\"},{\"downloads\":0,\"day\":\"2026-09-07\"},{\"downloads\":0,\"day\":\"2026-09-08\"},{\"downloads\":261183,\"day\":\"2026-09-09\"},{\"downloads\":268443,\"day\":\"2026-09-10\"},{\"downloads\":250050,\"day\":\"2026-09-11\"},{\"downloads\":164059,\"day\":\"2026-09-12\"},{\"downloads\":188684,\"day\":\"2026-09-13\"},{\"downloads\":339737,\"day\":\"2026-09-14\"},{\"downloads\":0,\"day\":\"2026-09-15\"},{\"downloads\":278779,\"day\":\"2026-09-16\"},{\"downloads\":280612,\"day\":\"2026-09-17\"},{\"downloads\":306045,\"day\":\"2026-09-18\"},{\"downloads\":387373,\"day\":\"2026-09-19\"},{\"downloads\":499412,\"day\":\"2026-09-20\"},{\"downloads\":395535,\"day\":\"2026-09-21\"},{\"downloads\":314788,\"day\":\"2026-09-22\"},{\"downloads\":316863,\"day\":\"2026-09-23\"},{\"downloads\":327024,\"day\":\"2026-09-24\"},{\"downloads\":334942,\"day\":\"2026-09-25\"},{\"downloads\":251678,\"day\":\"2026-09-26\"},{\"downloads\":298333,\"day\":\"2026-09-27\"}]}",
                    "pastedVersions": "{\"package\":\"left-pad\",\"downloads\":{\"0.0.2\":63,\"1.1.3\":5454,\"1.1.0\":4578,\"0.0.0\":322,\"0.0.4\":115,\"1.3.0\":4110106,\"0.0.9\":965,\"1.1.1\":266,\"0.0.3\":17604,\"1.0.2\":172,\"1.1.2\":395,\"1.0.0\":520,\"1.0.1\":138,\"1.2.0\":101325,\"0.0.1\":70}}"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SoftwareAdoptionExplorerResult"
                }
              }
            }
          },
          "400": {
            "description": "Malformed JSON body.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "Invalid input (see errors[]).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (see Retry-After).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tool": {
      "get": {
        "operationId": "getToolDefinition",
        "summary": "Inputs, output schema and examples for this tool",
        "responses": {
          "200": {
            "description": "Tool definition.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Problem": {
        "type": "object",
        "description": "RFC 9457 problem details. 422 responses include per-field `errors`.",
        "required": [
          "type",
          "title",
          "status",
          "detail"
        ],
        "properties": {
          "type": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": "integer"
          },
          "detail": {
            "type": "string"
          },
          "code": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "field",
                "message"
              ],
              "properties": {
                "field": {
                  "type": "string"
                },
                "message": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "SoftwareAdoptionExplorerInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "ecosystem": {
            "title": "Registry",
            "type": "string",
            "enum": [
              "npm",
              "pypi",
              "crates"
            ],
            "default": "npm"
          },
          "package": {
            "title": "Package name",
            "type": "string",
            "maxLength": 214
          },
          "includeDependents": {
            "title": "Look up dependents on deps.dev",
            "type": "boolean",
            "default": true
          },
          "pastedDownloads": {
            "title": "Pasted download JSON (offline)",
            "description": "npm /downloads/range/…, pypistats /overall or crates.io /crates/<name>/downloads.",
            "type": "string",
            "maxLength": 3000000
          },
          "pastedVersions": {
            "title": "Pasted version JSON (optional)",
            "description": "npm /versions/<pkg>/last-week, or crates.io /crates/<name> (maps version ids to numbers).",
            "type": "string",
            "maxLength": 3000000
          }
        },
        "required": []
      },
      "SoftwareAdoptionExplorerResult": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "schemaVersion",
          "tool",
          "computedAt",
          "inputs",
          "summary",
          "result",
          "units",
          "assumptions",
          "sources",
          "warnings",
          "presentation",
          "links"
        ],
        "properties": {
          "schemaVersion": {
            "type": "string",
            "const": "1.0"
          },
          "tool": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "id",
              "name",
              "version"
            ],
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "version": {
                "type": "string"
              }
            }
          },
          "computedAt": {
            "type": "string",
            "format": "date-time"
          },
          "inputs": {
            "type": "object",
            "description": "Normalised inputs actually used, including applied defaults."
          },
          "summary": {
            "type": "string"
          },
          "result": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "ecosystem",
              "package",
              "period",
              "totals",
              "weekly",
              "trend",
              "recent",
              "versions",
              "dependents",
              "registry"
            ],
            "properties": {
              "ecosystem": {
                "type": "string",
                "enum": [
                  "npm",
                  "pypi",
                  "crates"
                ]
              },
              "package": {
                "type": "string"
              },
              "period": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "start",
                  "end",
                  "days"
                ],
                "properties": {
                  "start": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "end": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "days": {
                    "type": "integer"
                  }
                }
              },
              "totals": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "downloads",
                  "avgDaily",
                  "zeroDays"
                ],
                "properties": {
                  "downloads": {
                    "type": "number"
                  },
                  "avgDaily": {
                    "type": "number"
                  },
                  "zeroDays": {
                    "type": "integer"
                  }
                }
              },
              "weekly": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "weekStart",
                    "downloads",
                    "days",
                    "partial"
                  ],
                  "properties": {
                    "weekStart": {
                      "type": "string"
                    },
                    "downloads": {
                      "type": "number"
                    },
                    "days": {
                      "type": "integer"
                    },
                    "partial": {
                      "type": "boolean"
                    }
                  }
                }
              },
              "trend": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "completeWeeks",
                  "last4Weeks",
                  "previous4Weeks",
                  "growthPct",
                  "first4Weeks",
                  "firstToLastPct",
                  "peakWeek",
                  "peakWeekDownloads"
                ],
                "properties": {
                  "completeWeeks": {
                    "type": "integer"
                  },
                  "last4Weeks": {
                    "type": "number"
                  },
                  "previous4Weeks": {
                    "type": [
                      "number",
                      "null"
                    ]
                  },
                  "growthPct": {
                    "type": [
                      "number",
                      "null"
                    ]
                  },
                  "first4Weeks": {
                    "type": [
                      "number",
                      "null"
                    ]
                  },
                  "firstToLastPct": {
                    "type": [
                      "number",
                      "null"
                    ]
                  },
                  "peakWeek": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "peakWeekDownloads": {
                    "type": [
                      "number",
                      "null"
                    ]
                  }
                }
              },
              "recent": {
                "type": [
                  "object",
                  "null"
                ],
                "additionalProperties": false,
                "required": [
                  "lastDay",
                  "lastWeek",
                  "lastMonth"
                ],
                "properties": {
                  "lastDay": {
                    "type": [
                      "number",
                      "null"
                    ]
                  },
                  "lastWeek": {
                    "type": [
                      "number",
                      "null"
                    ]
                  },
                  "lastMonth": {
                    "type": [
                      "number",
                      "null"
                    ]
                  }
                }
              },
              "versions": {
                "type": [
                  "object",
                  "null"
                ],
                "additionalProperties": false,
                "required": [
                  "window",
                  "total",
                  "items",
                  "byMajor",
                  "highestStable",
                  "highestStableSharePct"
                ],
                "properties": {
                  "window": {
                    "type": "string"
                  },
                  "total": {
                    "type": "number"
                  },
                  "items": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "additionalProperties": false,
                      "required": [
                        "version",
                        "downloads",
                        "sharePct"
                      ],
                      "properties": {
                        "version": {
                          "type": "string"
                        },
                        "downloads": {
                          "type": "number"
                        },
                        "sharePct": {
                          "type": "number"
                        }
                      }
                    }
                  },
                  "byMajor": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "additionalProperties": false,
                      "required": [
                        "major",
                        "downloads",
                        "sharePct"
                      ],
                      "properties": {
                        "major": {
                          "type": "string"
                        },
                        "downloads": {
                          "type": "number"
                        },
                        "sharePct": {
                          "type": "number"
                        }
                      }
                    }
                  },
                  "highestStable": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "highestStableSharePct": {
                    "type": [
                      "number",
                      "null"
                    ]
                  }
                }
              },
              "dependents": {
                "type": [
                  "object",
                  "null"
                ],
                "additionalProperties": false,
                "required": [
                  "version",
                  "dependentCount",
                  "directDependentCount",
                  "indirectDependentCount"
                ],
                "properties": {
                  "version": {
                    "type": "string"
                  },
                  "dependentCount": {
                    "type": "integer"
                  },
                  "directDependentCount": {
                    "type": "integer"
                  },
                  "indirectDependentCount": {
                    "type": "integer"
                  }
                }
              },
              "registry": {
                "type": [
                  "object",
                  "null"
                ],
                "additionalProperties": false,
                "required": [
                  "latestVersion",
                  "createdAt",
                  "allTimeDownloads"
                ],
                "properties": {
                  "latestVersion": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "createdAt": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "allTimeDownloads": {
                    "type": [
                      "number",
                      "null"
                    ]
                  }
                }
              }
            }
          },
          "units": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "assumptions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "sources": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "title"
              ],
              "properties": {
                "title": {
                  "type": "string"
                },
                "url": {
                  "type": "string"
                },
                "publisher": {
                  "type": "string"
                },
                "retrievedAt": {
                  "type": "string"
                },
                "note": {
                  "type": "string"
                }
              }
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "presentation": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "Display blocks used by the human page (same data)."
          },
          "links": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "human",
              "api",
              "openapi",
              "methodology"
            ],
            "properties": {
              "human": {
                "type": "string",
                "format": "uri"
              },
              "api": {
                "type": "string",
                "format": "uri"
              },
              "openapi": {
                "type": "string",
                "format": "uri"
              },
              "methodology": {
                "type": "string",
                "format": "uri"
              }
            }
          }
        }
      }
    }
  }
}