---
title: "Packages"
order: 7
---

The Packages API provides several `pgutil` commands (available as `pgutil packages`) and HTTP endpoints to query, download, publish, delete, and perform other operations on packages in package-based feeds, regardless of the package type.

## pgutil Commands

All HTTP endpoints of the Packages API are available as `pgutil` commands. 

To find the list of commands available in `pgutil`, simply run `pgutil packages`. See [Getting started with pgutil](/docs/proget/api/pgutil) to learn more.

## Available HTTP Endpoints

* [List Packages](/docs/proget/api/packages/list) - lists the packages in a feed,  filtered as specified
* [List Package Versions](/docs/proget/api/packages/list-versions) - describes all versions of a package, filtered as specified
* [Download Package](/docs/proget/api/packages/download) - downloads a package file
* [Upload Package](/docs/proget/api/packages/upload) - uploads a package file to a feed
* [Delete Package](/docs/proget/api/packages/delete) - deletes a package from a feed
* [Set Package Status](/docs/proget/api/packages/status) - sets the listed or deprecated status of a specified package
* [Repackage Package](/docs/proget/api/packages/repackage) - repackages a package
* [Promote Package](/docs/proget/api/packages/promote) - promotes a package

The Packages API is available starting from ProGet 2023.0

:::(Warning) (Local & Cached Packages Only)
With the exception of Repackage and Promote, these endpoints currently only work with packages stored in ProGet (i.e. local or cached packages). To query remote packages from connectors, you'll need to use the [API specific to the feed type](/docs/proget/api).

Also note that Maven, Docker, and Bower don't have "packages" like other feed types, and will not work with this API.
:::

## Authenticating to Packages API { #authentication }

The following is a summary of access types and their corresponding requirements for various API keys types and endpoints within this API.

| Access Type | Requirements |
| --- | --- |
| System API Keys | `Use/Manage Feeds`  
| Feed API Keys | `View/Download` is required for all endpoints<br/>`Add/Repackage` is required for [Upload Package](/docs/proget/api/packages/upload) and [Repackage Package](/docs/proget/api/packages/repackage)<br/>`Overwrite/Delete` is required for [Delete Package](/docs/proget/api/packages/delete)<br/>`Promote` is required for [Promote Package](/docs/proget/api/packages/promote)
| Personal API Key | `Feeds_ViewFeed` is required for all endpoints<br/>`Feeds_AddPackage` is required for [Upload Package](/docs/proget/api/packages/upload) and [Repackage Package](/docs/proget/api/packages/repackage)<br/>`Feeds_DeletePackage` is required for [Delete Package](/docs/proget/api/packages/delete)
| No API Key | anonymous or authenticated user must have at least `Feeds_ViewFeed`

To specify an API Key, use the request header (`X-ApiKey`), querystring (`key`), or `api:«api-key»` as the username. See [API Key Usage](/docs/proget/api/apikeys#using-api-keys) to learn more.

:::(Info) (🚀 Quick Example: Authenticating with curl)
For example, to authenticate with the API key `abc12345`  to the query packages endpoint, you could specify the API key as follows:

```bash
curl -X GET --header "X-ApiKey: abc12345" "https://proget.corp.local/api/packages/MyNugetFeed/versions"
```

If the provided API key is either missing, unknown/incorrect or does not have permission, the following message is returned:

```plaintext
403 The specified API key does not have the proper permissions to perform this action.
```
:::

## Package Identifiers (Group/Name/Version vs Purl) { #package-identifiers }

Endpoints that work with a single package version (e.g. downloading, deleting, etc.) require identifying a single version package using querystring parameters. This can be done by specifying multiple parameters (`name` and `version`, and sometimes `group` and `qualifier`) or a single parameter (`purl`).

### Using Multiple Parameters to Identify a Package { #using-multiple-parameters }
Identifying a package version requires up to four different components, depending on the type of package. 

| Argument | Details | Endpoints Used |
| --- | --- | --- |
|`name`| the name/id of package to download | `all`
|`version`| the version of package to download | `all`
|`group`| used only by Universal and npm feeds; for npm, this is the "scope" with the the `@` replaced by `%40` | `query package version`, `query latest package`, `download package`, `delete package`, `set package status`
|`qualifier`| used by some feeds (like Debian and rubygems) for attributes like architecture |`query package version`, `query latest package`, `download package`, `delete package`, `set package status`

::: (info) (🚀 Quick Example: Downloading an npm Package)
To download version `12.3.1` of the `@angular/animation` package, you would need to construct a url as follows:

```plaintext
/api/packages/NpmFeed/download?group=angular&name=animation&version=12.3.1
```
:::

::: (info) (🚀 Quick Example: Downloading a Debian Package)
To download version `3.9.2-3` of the `python3` package with the amd64 architecture, you would need to construct a url as follows:

```plaintext
/api/packages/MyDebianFeed/download?group=main&name=python3&version=3.9.2-3&qualifier=arch%3Damd64
 ```
:::

### Using a Purl to Identify a Package
To simplify package identification, you can also specify a `purl` (i.e. Package Url) that is compatible across all package types. These work with any endpoint that works with a single package version (e.g. deleting, downloading, promoting, etc.)

::: (info) (Example)
To download version 12.3.1 of the `@angular/animation` package, you would need to construct a `purl` as follows:

```plaintext
/api/packages/NpmFeed/download?purl=pkg:npm/%40angular/animation@12.3.1
```
:::

This follows the [purl-spec](https://github.com/package-url/purl-spec), and you can also find it on the [PackageVersion Object](#package-version)

::: (warn)
Note: `purl` are intended for single package endpoints only, and cannot be used with endpoints that return multiple packages (e.g. list, list versions, etc.)
:::

### Documentation Conventions
In the operations that require package version identifier, we will use `«package-identifiers»`to reference the one or multiple parameters that you can use.

## Data Specifications { #data-specifications }

### PackageVersionInfo Object Attributes { #package-version }

`PackageVersionInfo` is a JSON object (see [PackageVersionInfo.cs](https://github.com/Inedo/pgutil/blob/thousand/Inedo.ProGet/PackageVersionInfo.cs)) that corresponds to the fields on a Package. It's used as output data for [List Packages](/docs/proget/api/packages/list) and [List Package Versions](/docs/proget/api/packages/list-versions) as a JSON-formatted object.

#### Example JSON Object:
```json
[
    {
        "purl": "pkg:nuget/myNugetPackage@1.2.3",
        "name": "myNugetPackage",
        "version": "1.2.3",
        "totalDownloads": 0,
        "downloads": 0,
        "published": "2024-05-28T09:14:31.313Z",
        "publishedBy": "j.smith",
        "size": 2596051,
        "listed": false,
        "md5": "a80c7fb0a5437ce4fa16a664bcc95c60",
        "sha1": "50d8ccef2efbc9b5bfc38f7ae41c989de2011b55",
        "sha256": "3d21caf909f9db2b5d13249d6728c2506c55e72e2123fbe2af65a056c0a0bf9d",
        "sha512": "6934665f0479c58bbe996c44f2bf16d435a72f4d92795f0bc1d40cb0b234jh3jc...",
        "deprecated": true
    }
]
```

### PackageStatus Object Attributes { #package-status }

`PackageStatus` is a JSON object (see [PackageStatus.cs](https://github.com/Inedo/pgutil/blob/thousand/Inedo.ProGet/PackageStatus.cs)) that corresponds to the fields on a package's status. It's used as input data for [Set Package Status](/docs/proget/api/packages/status) as a JSON-formatted object.

#### Example JSON Object:
```json
{
    "listed": false,
    "allow": null, 
    "deprecated": true,
    "deprecationReason": "Legacy Package",
}
```

### PromotePackageInput Object Attributes { #promotion }

`PromotePackageInput` is a JSON object (see [PromotePackageInput.cs](https://github.com/Inedo/pgutil/blob/thousand/Inedo.ProGet/PromotePackageInput.cs)) that corresponds to the fields of a promotion. It's used as input data for [Promote Package](/docs/proget/api/packages/promote) as a JSON-formatted object.

#### Example JSON Object:
```json
{
  "name": "myNpmPackage",
  "group": "myScope",
  "version": "1.2.3",
  "fromFeed": "npm-unapproved",
  "toFeed": "npm-approved",
  "comments": "This package was approved by admin"
}
```