Backup npm / PyPI / Docker Hub Packages
Pricing
from $10.00 / 1,000 results
Backup npm / PyPI / Docker Hub Packages
Back up every published version of your npm, PyPI and Docker Hub packages, with metadata and READMEs. Paste package URLs and get a checksum-verified ZIP per version, plus one ZIP of everything.
Pricing
from $10.00 / 1,000 results
Rating
5.0
(2)
Developer
One Scales
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share
Introduction
Back up your npm, PyPI and Docker Hub packages in one run: the latest version, the newest few, every version ever published, or exactly the versions you name. Paste your package pages, and get a ZIP of each version with its files, metadata and README. A single ZIP of the whole batch comes at the end. Download links are private and expire after 24 hours by default, or any time you choose up to about a month.
Each version is downloaded exactly as the registry published it: the npm tarball, every PyPI wheel and source distribution, or the full Docker image for every platform. Each file is checked against the checksum the registry publishes, so you know the backup is byte-for-byte what your users install.
Back up only packages you own or are authorized to copy. Being public on a registry does not make a package free to copy. Each package's license and the registry's terms still apply, and you are responsible for how you use what you download.
Features
- Latest, newest N, every version, or exactly the one you name — npm, PyPI and Docker Hub in one run. By default you get the latest version of each package; set a number for the newest N, 0 for the full history, or put a version or tag in the URL to back up exactly that one.
- Checksum-verified — every file is checked against the registry's own checksum (npm integrity, PyPI SHA-256, Docker digests).
- Metadata and READMEs included — each version's ZIP carries its manifest or metadata and its README alongside the files.
- Restorable Docker images — each tag is saved as a standard OCI image layout covering every platform, ready for
skopeoordocker load. - Expiring download links — links last 24 hours by default; set anywhere from 1 hour to 730 hours (about one month). The final row downloads everything in one ZIP.
Use Cases
- Off-site copy of your releases — keep every version of your packages outside the registry, in case of account lockout, takedown or accidental unpublish.
- Release archive — a complete, dated history of everything you have shipped, with publish times.
- Recover an unpublished version — keep the exact artifact users installed, even if a version is later removed.
- Compliance and audit — prove what you released and when, with checksums that match the registry.
- Registry migration — pull down every version before moving packages to a private registry or another account.
- Organization-wide snapshots — back up all of your team's packages across npm, PyPI and Docker Hub in one run.
- Image retention — keep old Docker tags you have overwritten or that a retention policy might delete.
- Client handover — give a client every version of the packages you published for them.
Input
Configure the actor in the UI, or pass the same fields via the API.
| Field | Type | Required | Description |
|---|---|---|---|
Package URLs (packageUrls) | Array of strings | Yes | Package pages, one per line: npm (https://www.npmjs.com/package/name), PyPI (https://pypi.org/project/name/) or Docker Hub (https://hub.docker.com/r/owner/image, or https://hub.docker.com/_/image for official images). Shorthand also works: npm:name, pypi:name, docker:owner/image. Add a version or tag to back up exactly that version — see the table below. |
Backup Latest Versions (latestVersions) | Integer | No — defaults to 1 | How many of each package's newest versions to back up, by publish date. 1 backs up only the latest version, 0 backs up every published version, and any other number N backs up the newest N. Ignored for lines that name a specific version or tag. |
Download Link Expiry (hours) (linkExpiryHours) | Integer | No — defaults to 24 | How long the download links keep working. Minimum 1 hour, maximum 730 hours (about one month). |
Proxy Configuration (proxyConfiguration) | Object | No — defaults to residential | Proxy used to download from the registries, which reduces rate-limiting and blocking. The backups themselves are unaffected. |
{"packageUrls": ["https://www.npmjs.com/package/is-odd","https://pypi.org/project/sampleproject/","https://hub.docker.com/r/tianon/true"],"latestVersions": 1,"linkExpiryHours": 24,"proxyConfiguration": {"useApifyProxy": true,"apifyProxyGroups": ["RESIDENTIAL"]}}
Backing up a specific version
Put a version or tag in the line to back up exactly that version. A line that names a version ignores Backup Latest Versions: it always backs up that one version. Lines without a version still follow the setting, so you can mix both in one run.
| Registry | Whole package | One specific version |
|---|---|---|
| npm | https://www.npmjs.com/package/is-odd or npm:is-odd | https://www.npmjs.com/package/is-odd/v/2.0.0, npm:is-odd@2.0.0, or an npm tag such as npm:is-odd@latest / npm:name@beta (scoped: npm:@scope/name@1.0.0) |
| PyPI | https://pypi.org/project/sampleproject/ or pypi:sampleproject | https://pypi.org/project/sampleproject/1.3.1/ or pypi:sampleproject==1.3.1 |
| Docker Hub | https://hub.docker.com/r/tianon/true or docker:tianon/true (official images: https://hub.docker.com/_/nginx or docker:nginx) | docker:tianon/true:oci, a digest docker:tianon/true@sha256:…, or a tag page link https://hub.docker.com/layers/tianon/true/oci/… |
- A version that does not exist gets one error row, for example
error: version 9.9.9 not found on npm, with the version you asked for in theversioncolumn. - A version requested twice (for example pinned on one line and also picked as the latest on another) is backed up once, so you only pay for it once.
- npm tags (
latest,beta,next, …) back up the version the tag points to right now, and the row shows that version number.
For example, this backs up the latest is-odd, plus is-odd 2.0.0, plus exactly the oci tag of tianon/true:
{"packageUrls": ["https://www.npmjs.com/package/is-odd","https://www.npmjs.com/package/is-odd/v/2.0.0","docker:tianon/true:oci"],"latestVersions": 1}
Output
One row per version backed up (the latest one per package by default, plus any versions you named), grouped by package in the order you entered them and oldest version first, each with a download link. A package that cannot be found gets a single error row. The final row is the bulk download: one link to a ZIP of every version that was backed up successfully. Its fileCount is the number of versions it holds, and sizeBytes is their combined size.
| Field | Type | Description |
|---|---|---|
packageUrl | string | The package page that was requested, normalized |
registry | string | npm, pypi or docker |
packageName | string | Package name (npm and PyPI) or image name (Docker Hub) |
version | string | The published version (npm, PyPI) or tag (Docker Hub) |
publishedAt | string | When this version was published (ISO 8601, UTC) |
fileName | string | Name of the backup ZIP for this version |
fileCount | integer | Published files archived: the npm tarball, PyPI wheels and sdists, or Docker image blobs (versions on the final row) |
sizeBytes | integer | Size of the backup ZIP in bytes |
checksumVerified | boolean | true when every archived file matched the registry's published checksum |
downloadUrl | string | Download link for the backup, valid for linkExpiryHours (24 hours by default) |
backedUpAt | string | When the backup was taken (ISO 8601, UTC) |
status | string | success, or error: <reason> |
[{"packageUrl": "https://www.npmjs.com/package/is-odd","registry": "npm","packageName": "is-odd","version": "3.0.1","publishedAt": "2018-05-31T20:04:53.306Z","fileName": "npm-is-odd-3.0.1.zip","fileCount": 1,"sizeBytes": 10350,"checksumVerified": true,"downloadUrl": "https://api.apify.com/v2/key-value-stores/.../records?signature=...&prefix=pkg-00000-npm-is-odd-3.0.1.zip","backedUpAt": "2026-10-01T04:44:09.203Z","status": "success"},{"packageUrl": "ALL PACKAGES (ZIP)","registry": "N/A","packageName": "N/A","version": "N/A","publishedAt": "N/A","fileName": "all-packages.zip","fileCount": 3,"sizeBytes": 36161,"checksumVerified": false,"downloadUrl": "https://api.apify.com/v2/key-value-stores/.../records?signature=...&prefix=pkg-","backedUpAt": "2026-10-01T04:44:16.317Z","status": "success"}]
Good to know
- Your own packages only. Use it for packages you own or have permission to copy, and respect each package's license.
- What is in each version's ZIP:
- npm: the published
.tgztarball,metadata.json(that version's manifest) andREADME.md. The tarball also holds the README exactly as published with that version. - PyPI: every wheel and source distribution for the version,
metadata.jsonand that version's own README. - Docker Hub: an
image/folder in OCI image layout covering every platform of the tag, plusmetadata.jsonand the repository README. Restore withskopeo copy oci:image docker-daemon:name:tag, or tar the folder (tar -cf image.tar -C image .) and rundocker load -i image.tar.
- npm: the published
- Each link downloads a ZIP that contains the version's ZIP. That is how Apify serves expiring links. Unzip once to get the backup, and the bulk link gives you every backup in one ZIP.
- Download links expire. Each link works for
linkExpiryHourshours from when it was created (24 by default, 1 to 730 allowed), then returns an access error. After that, open the run's storage in the Apify Console, for as long as your plan keeps run data. A link set to 730 hours also stops early if the run's storage is deleted first. - Links are scoped to the run, not the file. Anyone who has a link and knows how to edit it can reach the other backups from the same run until it expires. Share links only with people you would share the whole run with.
- Specific versions: a line that names a version or tag backs up exactly that version and ignores Backup Latest Versions. See Backing up a specific version above.
- "Latest" means most recently published. Versions are ranked by publish date on every registry, so on npm a pre-release published after your last stable release counts as the latest. For Docker Hub, versions are tags, ranked by when they were last pushed. Versions with no publish date never count as the latest.
- Docker tags often share one image. A release is commonly pushed as
latest,1.4and1.4.2at once. With the default of 1 you get one of them, which is the same image either way. With higher numbers, tags that share an image are each backed up in full. - Versions with nothing to download (for example a PyPI release with no files) get an error row so you can see them.
- Docker Hub tags are listed up to 10,000 per image. Tags can be moved, so each backup is the tag as it is now. Non-distributable Windows base layers are not hosted on Docker Hub and are skipped. When that happens,
checksumVerifiedisfalseandmetadata.jsonrecords it. - Size limit: a single version over 2 GB is skipped with an error status. Files are streamed to disk, never held in memory.
- Retries: every download and file write is retried up to 3 times (2s, 8s, 20s), with a fresh proxy IP on each attempt. That includes Docker Hub's anonymous pull limit and any download whose checksum does not match. Permanent failures such as a 404 fail fast.
- Speed and memory: versions are backed up one at a time with a 2-second pause between them, to stay gentle on the registries. On the live registries that came to about 3–5 seconds per version: 18 versions across all three registries took under 90 seconds. That is roughly 12–20 versions a minute, so 100 versions take about 5–8 minutes. Large Docker images add their own download time. Memory stays flat at about 200 MB however large the files are, even for a 500 MB Docker image, so 512 MB is plenty.
- Proxy traffic: downloads go through a residential proxy by default, and residential traffic is billed per GB on your Apify account. For large Docker images, switch to datacenter proxies or turn the proxy off in the input.
- Pricing: pay-per-event, one row per version. You only pay for rows actually produced. Before downloading anything, the actor counts the versions you asked for, reads your spending limit and remaining account balance, backs up exactly as many versions as the budget covers, and never goes over it.
Support
Need help or want a feature added?
Contact Support at https://docs.google.com/forms/d/e/1FAIpQLSfsKyzZ3nRED7mML47I4LAfNh_mBwkuFMp1FgYYJ4AkDRgaRw/viewform?usp=dialog — Fill out this quick form.
We respond quickly and are happy to add new fields or custom integrations.
Tags
npm backup, pypi backup, docker hub backup, package backup, backup npm packages, backup pypi packages, backup docker images, download all versions, latest version download, specific version download, pinned version backup, npm all versions, pypi all versions, docker all tags, npm tarball download, pypi wheel download, sdist download, download docker image, oci image layout, oci archive, docker image backup, container image backup, release archive, package archive, artifact backup, software artifact archive, package version history, release history, npm unpublish recovery, registry migration, private registry migration, package mirror, npm mirror, pypi mirror, docker mirror, checksum verified, sha256 verification, npm integrity, software supply chain, open source maintainer tools, package maintainer backup, compliance archive, audit trail, disaster recovery, devops backup, python packages, javascript packages, node packages, container registry, zip archive, bulk download, expiring download links, apify actor