# Packagist

> Read the PHP package registry Composer installs from. Search all 460,000+ packages by name, keyword or Composer type, list everything one vendor publishes, and see what the ecosystem installs most this week. Read a package's description, licence, maintainers, repository, download counts and dependent count, walk its full version history, and pull any version's composer.json whole - including every dependency, with PHP and extension requirements counted apart from packages. Check any set of packages for known vulnerabilities, with each advisory's CVE, severity and affected version range, or poll the registry's change feed to react the moment a dependency ships. Every action reads: nothing here changes anything on Packagist. No account or API token required.

App · Code Repositories · 11 actions. Web page: https://docs.lodol.com/docs/integrations/packagist

## Actions

### Get a package

Get everything Packagist publishes about a package: what it is, its latest stable release, its licence, its repository, its maintainers, how many times it has been installed all time and in the last month, how many other packages depend on it, and its GitHub stars, forks and open issues. Also reports whether its author has marked it abandoned and what they suggest instead. The starting point for almost any workflow about a package. No account or API token required.

**Inputs**

- Package name (`package`, text, required): The package's name on Packagist, spelled vendor/package, e.g. monolog/monolog. Pasting the package's Packagist URL works too.

**Outputs**

- `branch_count` (number): How many are branches rather than releases.
- `latest_version` (object): The release Composer would install today: the highest stable version, not merely the most recently published one.
- `maintainers` (list): Who can publish new versions of it on Packagist.
- `package` (object): A package as Packagist describes it.
- `requested_name` (text): The name that was asked for.
- `resolved_name` (text): The spelling Packagist stores the package under.
- `tagged_version_count` (number): How many of those are tagged releases.
- `version_count` (number): How many versions it has published in total.

**Example output**

```json
{
  "branch_count": 6,
  "latest_version": {
    "is_default_branch": false,
    "is_development": false,
    "license": [
      "MIT"
    ],
    "published_at": "2026-01-02T08:56:22Z",
    "released_at": "2026-01-02T08:56:05Z",
    "requires_php": ">=8.1",
    "source_reference": "b321dd6749f0bf7189444158a3ce785cc16d69b0",
    "stability": "stable",
    "version": "3.10.0",
    "version_normalized": "3.10.0.0"
  },
  "maintainers": [
    {
      "avatar_url": "https://www.gravatar.com/avatar/b69782e1",
      "name": "Seldaek"
    }
  ],
  "package": {
    "abandoned": false,
    "created_at": "2011-09-27T00:35:19Z",
    "dependents": 8432,
    "description": "Sends your logs to files, sockets, inboxes, databases and various web services",
    "downloads_daily": 867783,
    "downloads_monthly": 19169183,
    "downloads_total": 1049453967,
    "favers": 22267,
    "github_forks": 1909,
    "github_open_issues": 25,
    "github_stars": 21399,
    "github_watchers": 304,
    "language": "PHP",
    "name": "monolog/monolog",
    "replacement_package": null,
    "repository": "https://github.com/Seldaek/monolog",
    "suggesters": 644,
    "type": "library",
    "url": "https://packagist.org/packages/monolog/monolog"
  },
  "requested_name": "monolog/monolog",
  "resolved_name": "monolog/monolog",
  "tagged_version_count": 87,
  "version_count": 93
}
```

### Get a package's download stats

Get a package's install counts - all time, the last month and the last day - along with every version it has published and the date Packagist started counting. The cheapest way to track adoption, and the step to chain when a workflow needs a package's version list without its whole manifest. No account or API token required.

**Inputs**

- Package name (`package`, text, required): The package's name on Packagist, spelled vendor/package, e.g. monolog/monolog. Pasting the package's Packagist URL works too.

**Outputs**

- `collected_since` (text): The date Packagist started counting downloads for this package, as YYYY-MM-DD.
- `downloads` (object): How often it has been installed.
- `package` (text): The package that was read.
- `url` (text): The package's page on Packagist.
- `version_count` (number): How many versions that is.
- `versions` (list): Every version it has published, newest first, as plain version strings.

**Example output**

```json
{
  "collected_since": "2012-04-13",
  "downloads": {
    "daily": 826453,
    "monthly": 19271863,
    "total": 1049556647
  },
  "package": "monolog/monolog",
  "url": "https://packagist.org/packages/monolog/monolog",
  "version_count": 93,
  "versions": [
    "dev-main",
    "3.10.0",
    "3.9.0"
  ]
}
```

### Get one version

Get one version's composer.json, whole: its description, authors, licence, keywords, autoload rules, executables, support links, funding links and every dependency block. Leave the version blank for the latest stable release, which is what Composer would install. Naming a branch such as dev-main works too. No account or API token required.

**Inputs**

- Package name (`package`, text, required): The package's name on Packagist, spelled vendor/package, e.g. monolog/monolog. Pasting the package's Packagist URL works too.
- Version (`version`, text): Optional. Which version to read. The list is fetched from Packagist, so it is always the versions this package actually published. Leave blank for the latest stable release, which is what Composer would install.

**Outputs**

- `is_latest_stable` (true/false): True when this is the release Composer would install. Useful for checking whether a pinned version is behind.
- `package` (text): The package it belongs to.
- `requested_version` (text): The version that was asked for. Null when the field was left blank.
- `resolved_version` (text): The version that was actually read - the latest stable release when none was named.
- `url` (text): The package's page on Packagist.
- `version` (object): The version's full composer.json metadata.

**Example output**

```json
{
  "is_latest_stable": true,
  "package": "monolog/monolog",
  "requested_version": null,
  "resolved_version": "3.10.0",
  "url": "https://packagist.org/packages/monolog/monolog",
  "version": {
    "authors": [
      {
        "email": "j.boggiano@seld.be",
        "homepage": "https://seld.be",
        "name": "Jordi Boggiano",
        "role": null
      }
    ],
    "autoload": {
      "psr-4": {
        "Monolog\\": "src/Monolog"
      }
    },
    "bin": [],
    "conflict": [],
    "description": "Sends your logs to files, sockets, inboxes, databases and various web services",
    "dist": {
      "reference": "b321dd6749f0bf7189444158a3ce785cc16d69b0",
      "shasum": null,
      "type": "zip",
      "url": "https://api.github.com/repos/Seldaek/monolog/zipball/b321dd6749f0bf7189444158a3ce785cc16d69b0"
    },
    "extra": {
      "branch-alias": {
        "dev-main": "3.x-dev"
      }
    },
    "funding": [
      {
        "type": "github",
        "url": "https://github.com/Seldaek"
      }
    ],
    "homepage": "https://github.com/Seldaek/monolog",
    "is_default_branch": false,
    "is_development": false,
    "keywords": [
      "log",
      "logging",
      "psr-3"
    ],
    "license": [
      "MIT"
    ],
    "name": "monolog/monolog",
    "provide": [
      {
        "constraint": "3.0.0",
        "name": "psr/log-implementation"
      }
    ],
    "published_at": "2026-01-02T08:56:22Z",
    "released_at": "2026-01-02T08:56:05Z",
    "replace": [],
    "require": [
      {
        "constraint": ">=8.1",
        "name": "php"
      },
      {
        "constraint": "^2.0 || ^3.0",
        "name": "psr/log"
      }
    ],
    "require_dev": [
      {
        "constraint": "^10.5.17 || ^11.0.7",
        "name": "phpunit/phpunit"
      }
    ],
    "requires_php": ">=8.1",
    "source": {
      "reference": "b321dd6749f0bf7189444158a3ce785cc16d69b0",
      "type": "git",
      "url": "https://github.com/Seldaek/monolog.git"
    },
    "source_reference": "b321dd6749f0bf7189444158a3ce785cc16d69b0",
    "stability": "stable",
    "suggest": [
      {
        "constraint": "Allow sending log messages to an AMQP server",
        "name": "ext-amqp"
      }
    ],
    "support": {
      "issues": "https://github.com/Seldaek/monolog/issues",
      "source": "https://github.com/Seldaek/monolog/tree/3.10.0"
    },
    "type": "library",
    "version": "3.10.0",
    "version_normalized": "3.10.0.0"
  }
}
```

### Get registry statistics

Get Packagist's own totals: how many packages it hosts, how many versions those add up to, and how many times anything has been installed. One small request, useful for a dashboard tile or for putting a single package's downloads in proportion. No account or API token required.

**Inputs**: None.

**Outputs**

- `downloads` (number): How many package installs Packagist has served in total.
- `packages` (number): How many packages it hosts.
- `url` (text): Packagist's statistics page.
- `versions` (number): How many versions those packages add up to.

**Example output**

```json
{
  "downloads": 195763100089,
  "packages": 465273,
  "url": "https://packagist.org/statistics",
  "versions": 5771319
}
```

### List a package's dependencies

List what one version of a package depends on, with the version constraint it asks for. Package dependencies and platform requirements (php, ext-json and the like) are returned separately, because an audit almost always wants them counted apart. Choose which blocks to read - what it needs to run, what it needs to test, what it suggests, what it provides, conflicts with or replaces. No account or API token required.

**Inputs**

- Package name (`package`, text, required): The package's name on Packagist, spelled vendor/package, e.g. monolog/monolog. Pasting the package's Packagist URL works too.
- Version (`version`, text): Optional. Which version to read. The list is fetched from Packagist, so it is always the versions this package actually published. Leave blank for the latest stable release, which is what Composer would install.
- Dependency blocks (`kinds`, text): Optional. Which composer.json blocks to read. What it needs to run and what it needs to test, by default. One or more of: `require` (Require - needed to install the package), `require-dev` (Require-dev - needed only to develop or test it), `suggest` (Suggest - optional extras its author recommends), `provide` (Provide - virtual packages it implements), `conflict` (Conflict - versions it cannot be installed alongside), `replace` (Replace - packages it stands in for).

**Outputs**

- `blocks` (object): The same dependencies grouped by block, under the keys require, require_dev, suggest, provide, conflict and replace - only the ones that were asked for.
- `count` (number): How many package dependencies there are.
- `dependencies` (list): The packages it depends on, each tagged with the block it came from.
- `kinds` (list): The blocks that were read.
- `package` (text): The package that was read.
- `platform_count` (number): How many platform requirements there are.
- `platform_requirements` (list): The requirements that are not packages: php itself, PHP extensions (ext-*) and system libraries (lib-*).
- `url` (text): The package's page on Packagist.
- `version` (text): The version whose dependencies these are.

**Example output**

```json
{
  "blocks": {
    "require": [
      {
        "constraint": ">=8.1",
        "name": "php"
      },
      {
        "constraint": "^2.0 || ^3.0",
        "name": "psr/log"
      }
    ],
    "require_dev": [
      {
        "constraint": "^10.5.17 || ^11.0.7",
        "name": "phpunit/phpunit"
      }
    ]
  },
  "count": 1,
  "dependencies": [
    {
      "constraint": "^2.0 || ^3.0",
      "kind": "require",
      "name": "psr/log"
    }
  ],
  "kinds": [
    "require",
    "require-dev"
  ],
  "package": "monolog/monolog",
  "platform_count": 1,
  "platform_requirements": [
    {
      "constraint": ">=8.1",
      "kind": "require",
      "name": "php"
    }
  ],
  "url": "https://packagist.org/packages/monolog/monolog",
  "version": "3.10.0"
}
```

### List a package's versions

List the versions a package has published, each with the date it went out, its licence, the PHP version it needs, the commit it was built from and whether it is a tagged release or a branch. Ordered by version number rather than by date, so a back-ported fix released last week does not appear to be the newest release. Use it to build a release history, to see how often a project ships, or to find every version still on a supported line. No account or API token required.

**Inputs**

- Package name (`package`, text, required): The package's name on Packagist, spelled vendor/package, e.g. monolog/monolog. Pasting the package's Packagist URL works too.
- Which releases (`releases`, text): Optional. Whether to list tagged releases, branches, or both. Tagged releases only by default, which is what Composer installs. One of: `tagged` (Tagged releases only - what Composer installs by default), `branches` (Branches only - dev-main, 2.x-dev and the like), `all` (Both tagged releases and branches). Default: `tagged`.
- Order by (`sort`, text): Optional. How to order the versions. Highest version number first by default. One of: `newest` (Highest version number first), `oldest` (Lowest version number first), `recent` (Most recently released first). Default: `newest`.
- How many versions (`limit`, number): Optional. How many versions to return. A long-lived package can have hundreds; 100 by default. From 1 to 10000. Default: `100`.

**Outputs**

- `count` (number): How many versions were returned.
- `latest_version` (object): The highest stable release, whatever the ordering and whatever the limit cut off.
- `package` (text): The package these versions belong to.
- `releases` (text): Which kinds of release were listed.
- `sort` (text): The ordering that was used.
- `total` (number): How many exist before the limit was applied.
- `truncated` (true/false): True when the limit cut some off.
- `url` (text): The package's page on Packagist.
- `versions` (list): The versions, in the order asked for.

**Example output**

```json
{
  "count": 1,
  "latest_version": {
    "is_default_branch": false,
    "is_development": false,
    "license": [
      "MIT"
    ],
    "published_at": "2026-01-02T08:56:22Z",
    "released_at": "2026-01-02T08:56:05Z",
    "requires_php": ">=8.1",
    "source_reference": "b321dd6749f0bf7189444158a3ce785cc16d69b0",
    "stability": "stable",
    "version": "3.10.0",
    "version_normalized": "3.10.0.0"
  },
  "package": "monolog/monolog",
  "releases": "tagged",
  "sort": "newest",
  "total": 87,
  "truncated": true,
  "url": "https://packagist.org/packages/monolog/monolog",
  "versions": [
    {
      "is_default_branch": false,
      "is_development": false,
      "license": [
        "MIT"
      ],
      "published_at": "2026-01-02T08:56:22Z",
      "released_at": "2026-01-02T08:56:05Z",
      "requires_php": ">=8.1",
      "source_reference": "b321dd6749f0bf7189444158a3ce785cc16d69b0",
      "stability": "stable",
      "version": "3.10.0",
      "version_normalized": "3.10.0.0"
    }
  ]
}
```

### List package names

List package names, filtered by vendor or by Composer type - every package one organization publishes, or every plugin of a given kind in the registry. Optionally return each name's repository, type and abandoned status alongside it. Use it to inventory what a team publishes, or to audit a whole class of package. Unfiltered this covers all 460,000+ packages, so it is cut to a length you choose. No account or API token required.

**Inputs**

- Vendor (`vendor`, text): Optional. Only packages published under this vendor (the part before the slash), e.g. symfony. Pasting a whole package name works - its vendor is used.
- Package type (`package_type`, text): Optional. Only packages declaring this Composer type. Types are free text chosen by each author, so this is not a fixed list - the common ones are library, project, metapackage and composer-plugin, plus framework-specific ones such as symfony-bundle or wordpress-plugin.
- Extra fields (`fields`, text): Optional. Extra details to return with each name. Leave empty for names only, which is the fastest. One or more of: `repository` (Repository - where the package's source lives), `type` (Type - library, project, composer-plugin and so on), `abandoned` (Abandoned - whether it is marked abandoned, and its replacement).
- How many names (`limit`, number): Optional. How many names to return. This listing is not paginated and answers with every match at once, so this is the cut-off; 100 by default. From 1 to 10000. Default: `100`.

**Outputs**

- `count` (number): How many names were returned.
- `filters` (object): The filters that were applied.
- `names` (list): The same packages as plain names, for a step that wants to loop over them.
- `packages` (list): The matching packages. Each carries its name and page, plus whichever extra fields were asked for.
- `total` (number): How many match before the limit was applied.
- `truncated` (true/false): True when the limit cut some off.

**Example output**

```json
{
  "count": 1,
  "filters": {
    "fields": [
      "repository",
      "type",
      "abandoned"
    ],
    "type": null,
    "vendor": "monolog"
  },
  "names": [
    "monolog/monolog"
  ],
  "packages": [
    {
      "abandoned": false,
      "name": "monolog/monolog",
      "replacement_package": null,
      "repository": "https://github.com/Seldaek/monolog",
      "type": "library",
      "url": "https://packagist.org/packages/monolog/monolog"
    }
  ],
  "total": 2,
  "truncated": true
}
```

### List popular packages

List the most-downloaded packages on Packagist, ranked by downloads over the past week rather than all time - so a package that was popular years ago does not hold the top spot. Each carries its description, downloads and popularity. Use it to see what the PHP ecosystem is actually installing today. No account or API token required.

**Inputs**

- Page (`page`, number): Optional. Which page of results to fetch. Use the next page from the previous result to walk through them. 1 by default. From 1 to 10000. Default: `1`.
- Results per page (`per_page`, number): Optional. How many results to return. Between 1 and 100, which is Packagist's own ceiling; 25 by default. From 1 to 100. Default: `25`.

**Outputs**

- `count` (number): How many packages this page holds.
- `has_more` (true/false): True when there is another page after this one.
- `next_page` (number): The page number to ask for next. Null on the last page.
- `packages` (list): The packages, most downloaded first.
- `page` (number): The page that was fetched.
- `per_page` (number): The page size that was used.
- `total` (number): How many packages Packagist ranks in total.

**Example output**

```json
{
  "count": 1,
  "has_more": true,
  "next_page": 2,
  "packages": [
    {
      "abandoned": false,
      "description": "Sends your logs to files, sockets, inboxes, databases and various web services",
      "downloads": 1048851145,
      "favers": 22267,
      "name": "monolog/monolog",
      "replacement_package": null,
      "repository": "https://github.com/Seldaek/monolog",
      "url": "https://packagist.org/packages/monolog/monolog",
      "virtual": false
    }
  ],
  "page": 1,
  "per_page": 25,
  "total": 465235
}
```

### List recent package changes

List every package whose metadata changed since a moment - the feed Composer mirrors poll. Each entry says which package changed, whether a release or a branch moved, and when. Run it once with the moment blank to get the cursor to start from, then hand each run's 'next since' to the next. Packagist keeps 24 hours of history, and says so when you ask for more. No account or API token required.

**Inputs**

- Changed since (`since`, date and time): Optional. List changes made after this moment. Leave blank on the first run: Packagist answers with the cursor to start from and no changes. Packagist keeps only the last 24 hours.
- Only these changes (`change_types`, text): Optional. Keep only these kinds of change. Both by default. One or more of: `update` (Update - the package's metadata changed), `delete` (Delete - the package was removed from Packagist).
- How many changes (`limit`, number): Optional. How many changes to return. A busy hour produces thousands; 100 by default. From 1 to 10000. Default: `100`.

**Outputs**

- `change_types` (list): The kinds of change that were kept.
- `changes` (list): The packages that changed, oldest first.
- `count` (number): How many changes were returned.
- `initialized` (true/false): True when this run only fetched the starting cursor because no moment was given.
- `next_since` (text): The moment to pass as 'since' on the next run, as an ISO 8601 UTC instant. It is rounded down to the second, so a change may occasionally be reported twice rather than missed.
- `requested_since` (text): The moment that was asked for, as an ISO 8601 UTC instant.
- `resync_required` (true/false): True when the moment asked for is older than the 24 hours Packagist keeps, so no list of changes can be given and anything cached should be re-read.
- `total` (number): How many changes matched before the limit was applied.
- `truncated` (true/false): True when the limit cut some off.

**Example output**

```json
{
  "change_types": [
    "update"
  ],
  "changes": [
    {
      "affects": "tagged releases",
      "changed_at": "2026-08-26T22:35:32Z",
      "package": "acme/package",
      "type": "update",
      "url": "https://packagist.org/packages/acme/package"
    }
  ],
  "count": 1,
  "initialized": false,
  "next_since": "2026-08-26T22:37:01Z",
  "requested_since": "2026-08-26T22:35:18Z",
  "resync_required": false,
  "total": 16,
  "truncated": true
}
```

### List security advisories

Check packages for known vulnerabilities, or fetch every advisory published since a moment. Each carries its CVE, its severity, the exact version range affected and where it was disclosed - so a workflow can decide whether the version you run is one of them. Packages Packagist knows and has nothing on are reported separately from ones it has never heard of, which is the difference between 'clean' and 'misspelled'. The step for a scheduled dependency audit. No account or API token required.

**Inputs**

- Packages to check (`packages`, list): The package names to check, spelled vendor/package. Give these or a date and time below - Packagist needs one of the two.
- Published since (`updated_since`, date and time): Optional. Fetch every advisory published or updated since this moment, across the whole registry, instead of checking named packages. Use the previous run's time to catch only what is new.
- Only these severities (`severities`, text): Optional. Keep only advisories graded at these levels. Leave empty for all of them, including the ones no source has graded. One or more of: `critical`, `high`, `medium`, `low`.

**Outputs**

- `advisories` (list): The advisories, most recently reported first.
- `affected_packages` (list): The packages at least one advisory names.
- `checked_packages` (list): The packages Packagist recognised. One that is here but not in affected_packages has no known vulnerability.
- `count` (number): How many advisories were returned.
- `filters` (object): What was asked for.
- `has_vulnerabilities` (true/false): True when anything was found, so a condition step reads the way you would say it aloud.
- `unknown_packages` (list): The names Packagist has no advisory data for at all - usually a misspelling or a package from a different repository.

**Example output**

```json
{
  "advisories": [
    {
      "advisory_id": "PKSA-dw7n-x7f5-zf63",
      "affected_versions": ">=7.4.0,<7.4.12|>=8.0.0,<8.0.12",
      "composer_repository": "https://packagist.org",
      "cve": "CVE-2026-45075",
      "link": "https://symfony.com/cve-2026-45075",
      "package": "symfony/http-kernel",
      "reported_at": "2026-05-20T08:00:00Z",
      "severity": "high",
      "sources": [
        {
          "name": "GitHub",
          "remote_id": "GHSA-6439-2f28-8p8q"
        }
      ],
      "title": "CVE-2026-45075: HEAD Request Bypasses methods: ['GET'] Filter in #[IsGranted]"
    }
  ],
  "affected_packages": [
    "symfony/http-kernel"
  ],
  "checked_packages": [
    "monolog/monolog",
    "symfony/http-kernel"
  ],
  "count": 1,
  "filters": {
    "packages": [
      "symfony/http-kernel",
      "monolog/monolog"
    ],
    "severities": [
      "critical",
      "high"
    ],
    "updated_since": null
  },
  "has_vulnerabilities": true,
  "unknown_packages": []
}
```

### Search packages

Search the PHP package registry for packages by name, description and keyword, or browse it by tag or by Composer type. Each hit carries the package's description, its repository, its all-time downloads and its popularity, so a shortlist needs one step rather than one per candidate. The starting point for 'what is there for X in PHP?'. No account or API token required.

**Inputs**

- Search text (`query`, text): What to search for. Packagist matches names, descriptions and keywords. Optional if you filter by tag or type instead.
- Tags (`tags`, list): Optional. Only packages carrying every one of these keywords. Tags are free text chosen by each author, so a package's own page is the way to see which it uses.
- Package type (`package_type`, text): Optional. Only packages declaring this Composer type. Types are free text chosen by each author, so this is not a fixed list - the common ones are library, project, metapackage and composer-plugin, plus framework-specific ones such as symfony-bundle or wordpress-plugin.
- Page (`page`, number): Optional. Which page of results to fetch. Use the next page from the previous result to walk through them. 1 by default. From 1 to 10000. Default: `1`.
- Results per page (`per_page`, number): Optional. How many results to return. Between 1 and 100, which is Packagist's own ceiling; 25 by default. From 1 to 100. Default: `25`.

**Outputs**

- `count` (number): How many packages this page holds.
- `filters` (object): The tag and type filters that were applied.
- `has_more` (true/false): True when there is another page after this one.
- `next_page` (number): The page number to ask for next. Null on the last page.
- `packages` (list): The matching packages, best match first.
- `page` (number): The page that was fetched.
- `per_page` (number): The page size that was used.
- `query` (text): The search text that was used.
- `total` (number): How many packages match in total.

**Example output**

```json
{
  "count": 1,
  "filters": {
    "tags": [],
    "type": null
  },
  "has_more": true,
  "next_page": 2,
  "packages": [
    {
      "abandoned": false,
      "description": "Sends your logs to files, sockets, inboxes, databases and various web services",
      "downloads": 1048851145,
      "favers": 22267,
      "name": "monolog/monolog",
      "replacement_package": null,
      "repository": "https://github.com/Seldaek/monolog",
      "url": "https://packagist.org/packages/monolog/monolog",
      "virtual": false
    }
  ],
  "page": 1,
  "per_page": 25,
  "query": "monolog",
  "total": 1124
}
```
