First package? Follow the publish and install quickstart →
Overview
This guide tells you how to find the download numbers of your private packages and how to read them correctly. You examine the monthly traffic of the organization and the downloads of one package by version and by recipient. You also examine one recipient and one download key. At the end, you can make an adoption report for your recipients.
The guide is for organization admins, release managers and the people who report package use to customers or to management. The examples use the scope @acme, the package @acme/sdk and the shared registry at registry.privatenpm.com.
PrivateNPM keeps more than one counter. Each counter answers a different question. Before you use a number in a report, read How the registry counts downloads. The section tells you which counter gives which number, and why two pages can show different values for the same package.
Before you start
Make sure that these conditions are true:
- You are a member of the organization that owns the registry.
- Your role includes
npm:package:read. All built-in roles include this permission. - For recipient names and for the recipient pages, your role includes
registry:download_key:manage. - For single transfers, the CSV export and the Registry activity page, your role includes
registry:transfer:read. - Each recipient installs with a download key (
pdk_…) that is linked to a recipient record.
The built-in admin role has all of these permissions. The member and viewer roles can read the package pages, but they cannot see recipient names or single transfers. For the management API examples, you also need an API key (gsk_…) with registry:transfer:read. API access starts on the Growth plan.
How the registry counts downloads
What the registry records
When a client such as npm installs a package, it sends two kinds of requests. First, it requests the package metadata, which lists the versions and their tarball URLs. Then, it requests the tarball, which is the archive that contains the package content. PrivateNPM counts a download only for a tarball request. The registry measures metadata requests, but a metadata request is not a download and does not add to the egress of the organization.
Each request that the registry serves makes one usage event. The event carries a receipt identifier. The registry records the receipt first, and it ignores a second event with the same receipt. Thus, a network retry between the data plane and the registry does not count one download two times.
For each new tarball event, the registry writes one row in the transfer ledger. The row holds the time, the package, the version, the bytes sent, the credential, the recipient and the client. If your settings permit it, the row also holds the client IP address. The registry also adds the event to a queue of counter contributions.
Why the numbers trail by a short interval
A download never writes to a shared counter row. A background process, the usage fold, reads the queue at a fixed interval, adds the contributions together and writes the totals. This design keeps downloads fast when many clients install at the same time. The result is that charts and totals trail the newest downloads by a short interval, normally a few seconds. The transfer ledger shows a new row immediately.
The registry stores each download on the UTC day when it occurred. The monthly counters use UTC calendar months. If your time zone is not UTC, a download near midnight can appear on the previous day or the next day in a chart.
The four counters
| Counter | What it counts | Where it appears |
|---|---|---|
| Monthly usage | All tarball downloads and egress bytes in the organization for the UTC month, with all credentials. | Overview page, Plan & usage page |
| Delivery history | Tarball downloads through download keys, by day, package, version, key and recipient. | Package Downloads section, recipient pages, Recipients list |
| Transfer ledger | One row for each observed content transfer, downloads and publishes. | Registry activity page, Recent downloads, recipient CSV, API |
| Key usage | All authenticated registry requests of one key, metadata included. | Key usage chart and Last used on the key page |
The delivery history counts only downloads that use a download key. Downloads with a publisher key or a browser session add to the monthly usage, but not to the delivery history. Public packages that public npm caching serves also add to the monthly usage only.
NOTE: A client that installs from its local cache does not send a tarball request. The registry cannot count that install. The download numbers count requests that reach the registry, not machines or people.
Check the monthly traffic of the organization
Use this procedure to find the total downloads and the egress of the current month.
- Open the dashboard. The Overview page opens.
- Find the Downloads card. The card shows the downloads of this month in UTC.
- Open Organization → Plan & usage.
- Find the Monthly bandwidth egress meter in the Usage section.
- Compare the used bytes with the allowance of your plan. The meter also shows the plan rate and an estimate for the end of the month.
Egress is the number of content bytes that the registry sends to clients. The registry measures the uploads of npm publish, but uploads do not count as egress. The allowance is a soft monthly limit in decimal units: 1 GB is 1,000,000,000 bytes.
| Plan | Monthly egress allowance | Overage price |
|---|---|---|
| Starter | 10 GB | $0.15 for each GB |
| Growth | 100 GB | $0.15 for each GB |
| Scale | 500 GB | $0.12 for each GB |
| Platform | 3 TB | $0.10 for each GB |
Downloads never stop when the organization goes above the allowance. At the end of the month, the platform calculates an overage charge in whole GB, rounded down. The first month above the allowance and a trial month have no charge. The Bandwidth overage section shows the charge history and the spend cap. The spend cap limits the overage charge, and its default value is the price of one month of your plan.
The daily check sends a notification when the egress reaches 80%, 100% and 150% of the allowance. It also sends a notification when the projected charge reaches the spend cap.
See the downloads of a package
The package page breaks the downloads of the last 30 days down by version and by recipient. Use this procedure to find which releases your recipients install.
- Open Registry → Packages.
- Select the package, for example
@acme/sdk. The package page opens. - Find the Downloads section. The section shows the total downloads, the bytes delivered and a chart with one bar for each day.
- To read the exact daily values, open View daily values.
- Examine the By version table. The table shows the downloads and the bytes of each version.
- Examine the By recipient table. Each recipient name links to the recipient page.
The page shows the By recipient table only to people with registry:download_key:manage. Other readers see the total, the chart and the version table. The table groups downloads from a key that has no recipient link under one row without a recipient link.
If your role includes registry:transfer:read, the page also shows two sections from the transfer ledger. Downloads by version is a bar chart of the last 30 days. Recent downloads lists the latest 50 transfers with the time, the key, the recipient, the IP address and the client.
NOTE: The Downloads section counts only downloads through download keys. The Downloads by version chart counts the ledger rows of all credentials. If your developers install with publisher keys, the chart can show a larger number than the section.
The registry records the delivery history by package name. Thus, a new package with the name of a deleted package also shows the history of the deleted package.
See the downloads of a recipient
A recipient groups the download keys of one person, team or company. Use this procedure to find what one recipient installs.
- Open Registry → Recipients. The list shows each recipient with its reference, the downloads of the last 30 days and its status.
- Select a recipient. The recipient page opens.
- Find the Delivery activity section. The section shows the downloads, the bytes delivered and a daily chart.
- Examine the By package table.
- To see each day, package and version, open Daily breakdown by package and version.
- Examine Rejected requests. The table lists authorization denials for the keys of the recipient.
The recipient page counts only downloads through keys that are linked to the recipient. A key that you link later adds its new downloads to the recipient. The earlier downloads of that key stay in the history without a recipient link.
Export the recipient usage CSV
The recipient page has two export buttons: Export 30 days CSV and Export 90 days CSV. The file has one row for each transfer of the recipient in the transfer ledger. You need registry:transfer:read to export the file.
The file recipient-usage.csv has these columns: occurred_at, package, version, file, direction, status, bytes, credential_id, client, country and client_ip. The times are in RFC 3339 UTC format.
The transfer ledger keeps rows for a period that your plan sets: 30 days on Starter, 90 days on Growth, 180 days on Scale and 400 days on Platform. On Starter, the 90-day export contains a maximum of 30 days. If you must keep a longer record, download the file at a regular interval.
Check the activity of a download key
Use this procedure to find whether a recipient uses a key.
- Open Registry → Registry keys. The Download keys table shows the recipient, the package access, Last used and the status of each key.
- Select the key. The key page opens.
- Read Last used below the key name.
- Examine the Key usage chart. The chart shows the authenticated registry requests of the last 30 days.
- Examine the latest transfers of the key in Recent downloads.
Last used is an activity signal, not a download count. The registry updates the value a maximum of one time in 5 minutes for each key. The Key usage chart counts metadata requests too, so its numbers are larger than the download numbers. Use the key page to find whether a key is active, and use the delivery history to count downloads.
Examine single transfers
Open Registry → Activity to read the transfer ledger. The page answers who downloaded or published which package, when, from where and with which credential. Use the filters to limit the list by registry, package, version, direction, status, credential, recipient, member, IP address range or date range. The Access denied tab lists the requests that the registry refused.
The management API gives the same data. GET /api/v1/transfers lists the ledger rows, and GET /api/v1/transfers/summary adds them together by one dimension. The groupBy value is one of day, package, version, credential, recipient, country or client.
Report recipient adoption
An adoption report tells you which recipients install which releases. Make sure that each recipient has its own keys and that each key is linked to the recipient. Then do these steps for each report period:
- Open Registry → Recipients and record the downloads of each recipient for the last 30 days.
- Open the page of each package that you report.
- Record the By version table to see which releases the recipients install.
- Record the By recipient table to see which recipients install the package.
- For a recipient with zero downloads, open the recipient page and examine Rejected requests.
- For a recipient with zero downloads and no rejected requests, examine Last used on each key of the recipient.
To automate the report, request a summary by recipient from the management API. This request counts the downloads of @acme/sdk in September 2026:
curl -G https://privatenpm.com/api/v1/transfers/summary \
-H "Authorization: Bearer $ACME_API_KEY" \
--data-urlencode "groupBy=recipient" \
--data-urlencode "direction=download" \
--data-urlencode "packageName=@acme/sdk" \
--data-urlencode "startTime=2026-09-01T00:00:00Z" \
--data-urlencode "endTime=2026-10-01T00:00:00Z"The response has one group for each recipient ID. The API returns 64-bit numbers as strings:
{
"groups": [
{"key": "rrec_01J9Z3K8Q4", "requests": "412", "bytes": "98304000"},
{"key": "rrec_01J9Z3M2T7", "requests": "57", "bytes": "13631488"}
],
"totalRequests": "469",
"totalBytes": "111935488"
}The startTime value is inclusive and the endTime value is exclusive. Get the name of each recipient with GET /api/v1/recipients/{id}. That request needs registry:download_key:manage on the API key.
Read the numbers with care. One CI pipeline can download the same version many times in one day. A team that uses a local cache can install the package many times with few downloads. Report downloads as an activity trend, not as a count of users.
Verify the result
Do this test to make sure that the counters attribute downloads to the correct recipient:
- Create a test recipient on Registry → Recipients.
- Create a download key for the test recipient with access to
@acme/sdk. - In a new, empty directory, configure
.npmrcwith the key, as the .npmrc guide shows. - Run
npm install @acme/sdk --prefer-online --cache ./empty-cache. The empty cache makes npm send a tarball request. - Wait a few seconds for the usage fold.
- Open the package page. The By recipient table shows the test recipient with one download.
- Open the test recipient page. The Delivery activity section shows the same download.
If the test passes, revoke the test key on its key page. The download stays in the history.
Troubleshoot
| Symptom | Cause | Correction |
|---|---|---|
| A new download does not appear in the chart. | The usage fold did not add the download yet. | Wait a few seconds and load the page again. Examine the Registry activity page for the ledger row. |
| An install does not add a download. | The client installed from its local cache and sent no tarball request. | Install with an empty cache, as the verification procedure shows. |
| The Downloads section shows fewer downloads than the Overview page. | The section counts only download keys. The Overview counts all credentials and the whole organization. | Use the counter that matches your question. See the table of counters. |
| The By recipient table is absent. | Your role does not include registry:download_key:manage. | Ask an organization admin for the permission or for the report. |
| Downloads show without a recipient link. | The key had no recipient link at the time of the download. | Open the key page and link the key to a recipient. New downloads then show the recipient. |
| Last used shows an old time after an install. | The registry updates Last used a maximum of one time in 5 minutes. | Wait 5 minutes. Use Recent downloads for the exact time. |
| The 90-day CSV contains fewer than 90 days. | The transfer retention of your plan is shorter than 90 days. | Export at a regular interval, or change to a plan with a longer retention. |
The API returns 403 with api access is not enabled for this organization. | The plan of the organization does not include API access. | Change to Growth or a higher plan. |
Security and maintenance
The download numbers are only as accurate as the attribution of your keys. Do these tasks at a regular interval:
- Give each recipient and each automated system its own download key. A shared key makes the numbers of two recipients into one number.
- Link each download key to a recipient. Use the recipient reference to connect the record to your customer system.
- Examine keys with no Last used value or an old value. Revoke the keys that nobody uses.
- Examine Rejected requests to find revoked or expired keys that clients still send.
- Give
registry:transfer:readonly to the people who must see single transfers.
The transfer ledger and the recipient CSV can contain client IP addresses. Treat the exports as personal data. Store them in a location with access control, and delete them when you no longer need them.
WARNING: Do not send a recipient CSV to a different recipient. The file contains the IP addresses, clients and key identifiers of the recipient.
Related guides
- Automate npm download keys after a sale issues a linked key for each recipient.
- Recipient npm download portal lets recipients manage their own keys.
- Configure private registry webhooks sends key and recipient changes to your server.
- Authenticate npm with .npmrc configures a client with a download key.
- The management API reference describes the transfers endpoints.