Skip to content

DEVELOPER DOCUMENTATION / OPENAPI 3.0

Build on your registry.

Automate registries, scopes, packages, publisher keys, and customer download access with a straightforward JSON API.

GET STARTED

Your first request

Generate a management API key in Settings → API keys, grant it npm:package:read, and send it as a bearer token. The key acts within the organization that created it.

TerminalList registries
curl https://privatenpm.com/api/v1/registries \ -H "Authorization: Bearer $API_KEY"

The JSON response includes your private registries and the shared registry. Save the returned IDs for operations that target a registry.

01 / ACCESS

Authentication

Every management endpoint requires an organization API key in the Authorization: Bearer header. Give each integration only the permissions shown on the operations it calls. A 401 means the key is missing or invalid; a 403 means it lacks permission.

Three credentials, three jobs.

Management API keys call this API. Publisher keys authenticate npm publish and package maintenance. Download keys grant registry read access to customers. Treat all three as secrets; issued publisher and download key values appear only once.

02 / CONVENTIONS

Requests and responses

JSON over HTTPS

Use https://privatenpm.com/api/v1 as the base URL. Send Content-Type: application/json when there is a request body. Omit optional properties you are not setting.

Pagination

List endpoints that return nextPageToken can be paged by sending that value as pageToken. Continue until no token is returned.

Safe retries

Operations marked “Idempotency-Key supported” accept a unique Idempotency-Key header. Reuse the same key when retrying the same request.

Errors

Failures return JSON with a stable code and readable message. Handle 429 with backoff; 409 indicates a conflict or stale update.

JSONError response
{ "code": "permission_denied", "message": "This API key cannot perform this action." }

03 / WORKFLOWS

What you can build

INTEGRATION PATTERN

Publish from CI

  1. Create package metadata and record the package ID.
  2. Issue a publisher key limited to the registry or package, with publish permission.
  3. Store the one-time secret in your CI secret store and publish the tarball with npm.

Read the publishing guide ↗

INTEGRATION PATTERN

Deliver customer access

  1. Issue a download key for the purchased package IDs.
  2. Show the one-time secret to the customer over a secure channel.
  3. Rotate or revoke the key when access changes.

Read the download key guide ↗

ENDPOINT REFERENCEOpenAPI source ↗

API REFERENCE

Registries

Registries

List registries

#
GET/api/v1/registries

Includes the shared registry and your private registries.

Permission npm:package:read

Response 200 RegistryList

View response fields
registriesRegistry[]

Registries

Create a private registry

#
POST/api/v1/registries

Save the DNS verification challenge returned here.

Permission npm:registry:manage

JSON request body CreateRegistry

displayNamestring required
hostnamestring required

Response 201 Registry

View response fields
createdAtdate-time
displayNamestring
formatstring
hostnamestring
idstring
kindshared | private
tenantIdstring
verificationChallengestring
verificationExpiresAtdate-time

Registries

Delete an empty private registry

#
DELETE/api/v1/registries/{id}

A registry with packages, scopes, domains or credentials cannot be deleted.

Permission npm:registry:manage

Parameters

idpathstring

Response 204

No response body.

API REFERENCE

Scopes

Scopes

List registry scopes

#
GET/api/v1/registries/{registryId}/scopes
Permission npm:package:read

Parameters

registryIdpathstring

Response 200 ScopeList

View response fields
scopesScope[]

Scopes

Create a scope in a private registry

#
POST/api/v1/registries/{registryId}/scopes
Permission npm:scope:manage

Parameters

registryIdpathstring

JSON request body ScopeName

namestring required

With or without the leading @.

Response 201 Scope

View response fields
createdAtdate-time
idstring
namestring
registryIdstring

Scopes

Reserve your shared registry scope

#
POST/api/v1/scopes/shared

An organization may reserve one shared scope.

Permission npm:scope:manage

JSON request body ScopeName

namestring required

With or without the leading @.

Response 201 Scope

View response fields
createdAtdate-time
idstring
namestring
registryIdstring

Scopes

Delete an unused scope

#
DELETE/api/v1/scopes/{id}
Permission npm:scope:manage

Parameters

idpathstring

Response 204

No response body.

API REFERENCE

Packages

Packages

List packages

#
GET/api/v1/packages

Follow nextPageToken until empty.

Permission npm:package:read

Parameters

registryIdquerystring
queryquerystring
pageSizequeryint32
pageTokenquerystring

Response 200 PackageList

View response fields
nextPageTokenstring
packagesPackage[]

Packages

Create package metadata

#
POST/api/v1/packages

Publish a tarball with npm using a publisher key. Supports Idempotency-Key.

Permission npm:package:create Idempotency-Key supported

JSON request body CreatePackage

descriptionstring
namestring required
registryIdstring required
visibilityprivate | public

Response 201 Package

View response fields
createdAtdate-time
descriptionstring
etagstring
idstring
namestring
readmestring
registryIdstring
updatedAtdate-time
visibilityprivate | public

Packages

Delete an empty package

#
DELETE/api/v1/packages/{id}
Permission npm:package:delete

Parameters

idpathstring

Response 204

No response body.

Packages

Get package

#
GET/api/v1/packages/{id}
Permission npm:package:read

Parameters

idpathstring

Response 200 Package

View response fields
createdAtdate-time
descriptionstring
etagstring
idstring
namestring
readmestring
registryIdstring
updatedAtdate-time
visibilityprivate | public

Packages

Update package metadata

#
PATCH/api/v1/packages/{id}

Send the latest etag to reject stale edits.

Permission npm:package:update

Parameters

idpathstring

JSON request body UpdatePackage

descriptionstring
etagstring
readmestring
visibilityprivate | public

Response 200 Package

View response fields
createdAtdate-time
descriptionstring
etagstring
idstring
namestring
readmestring
registryIdstring
updatedAtdate-time
visibilityprivate | public

Packages

Remove a dist tag

#
DELETE/api/v1/packages/{packageId}/dist-tags/{tag}
Permission npm:package:update

Parameters

packageIdpathstring
tagpathstring

Response 204

No response body.

Packages

Set a dist tag

#
PUT/api/v1/packages/{packageId}/dist-tags/{tag}
Permission npm:package:update

Parameters

packageIdpathstring
tagpathstring

JSON request body TagVersion

versionstring required

Response 200 DistTag

View response fields
tagstring
versionstring

Packages

List versions and dist tags

#
GET/api/v1/packages/{packageId}/versions
Permission npm:package:read

Parameters

packageIdpathstring

Response 200 VersionList

View response fields
distTagsDistTag[]
versionsPackageVersion[]

Packages

Unpublish a version

#
DELETE/api/v1/versions/{id}
Permission npm:package:delete

Parameters

idpathstring

Response 204

No response body.

Packages

Deprecate or undeprecate a version

#
PUT/api/v1/versions/{id}/deprecation

Set message to an empty string to clear deprecation.

Permission npm:package:update

Parameters

idpathstring

JSON request body Deprecation

messagestring required

Response 204

No response body.

API REFERENCE

Publisher keys

Publisher keys

List publisher keys

#
GET/api/v1/publisher-keys
Permission registry:credential:manage

Parameters

pageSizequeryint32
pageTokenquerystring

Response 200 PublisherKeyList

View response fields
keysPublisherKey[]
nextPageTokenstring

Publisher keys

Issue a publisher key

#
POST/api/v1/publisher-keys

The secret is shown once. Not idempotent; a retry issues a new key.

Permission registry:credential:manage

JSON request body IssuePublisherKey

allPackagesboolean
expiresAtdate-time
namestring required
packageIdsstring[]
permissionsmetadata:read | tarball:read | identity:read | package:publish | dist-tag:write | package:unpublish[] required
registryIdsstring[] required
scopeIdsstring[]
userIdstring

Omit for the caller.

Response 201 IssuedPublisherKey

View response fields
keyPublisherKey
secretstring

Shown once.

Publisher keys

Revoke a publisher key

#
DELETE/api/v1/publisher-keys/{id}
Permission registry:credential:manage

Parameters

idpathstring

Response 204

No response body.

Publisher keys

Get publisher key metadata

#
GET/api/v1/publisher-keys/{id}

The secret is never returned here.

Permission registry:credential:manage

Parameters

idpathstring

Response 200 PublisherKey

View response fields
allPackagesboolean
createdAtdate-time
displayPrefixstring
expiresAtdate-time
idstring
lastUsedAtdate-time
namestring
packageIdsstring[]
permissionsstring[]
registryIdsstring[]
revokedboolean
scopeIdsstring[]
subjectKindstring

Always publisher.

userIdstring

Publisher keys

Rotate a publisher key

#
POST/api/v1/publisher-keys/{id}/rotate

Save the new secret; the old one stops working. Not idempotent; a retry rotates again.

Permission registry:credential:manage

Parameters

idpathstring

Response 200 IssuedPublisherKey

View response fields
keyPublisherKey
secretstring

Shown once.

API REFERENCE

Download keys

Download keys

List download keys

#
GET/api/v1/download-keys
Permission registry:download_key:manage

Parameters

pageSizequeryint32
pageTokenquerystring

Response 200 DownloadKeyList

View response fields
keysDownloadKey[]
nextPageTokenstring

Download keys

Issue a customer download key

#
POST/api/v1/download-keys

The secret is shown once. Not idempotent; a retry issues a new key.

Permission registry:download_key:manage

JSON request body IssueDownloadKey

allPackagesboolean
expiresAtdate-time
externalRefstring
namestring required
packageIdsstring[]
recipientstring required
registryIdstring required
scopeIdstring

Response 201 IssuedDownloadKey

View response fields
keyDownloadKey
secretstring

Shown once.

Download keys

Revoke a download key

#
DELETE/api/v1/download-keys/{id}
Permission registry:download_key:manage

Parameters

idpathstring

Response 200 DownloadKey

View response fields
allPackagesboolean
createdAtdate-time
credentialVersionstring
displayPrefixstring
expiresAtdate-time
externalRefstring
idstring
lastUsedAtdate-time
namestring
packageIdsstring[]
recipientstring
registryIdstring
revokedAtdate-time
scopeIdstring

Download keys

Get download key metadata

#
GET/api/v1/download-keys/{id}
Permission registry:download_key:manage

Parameters

idpathstring

Response 200 DownloadKey

View response fields
allPackagesboolean
createdAtdate-time
credentialVersionstring
displayPrefixstring
expiresAtdate-time
externalRefstring
idstring
lastUsedAtdate-time
namestring
packageIdsstring[]
recipientstring
registryIdstring
revokedAtdate-time
scopeIdstring

Download keys

Change download access

#
PATCH/api/v1/download-keys/{id}

Supply exactly one of allPackages, scopeId or packageIds.

Permission registry:download_key:manage

Parameters

idpathstring

JSON request body DownloadAccess

allPackagesboolean
packageIdsstring[]
scopeIdstring

Response 200 DownloadKey

View response fields
allPackagesboolean
createdAtdate-time
credentialVersionstring
displayPrefixstring
expiresAtdate-time
externalRefstring
idstring
lastUsedAtdate-time
namestring
packageIdsstring[]
recipientstring
registryIdstring
revokedAtdate-time
scopeIdstring

Download keys

Rotate a download key

#
POST/api/v1/download-keys/{id}/rotate

Save the new secret. Not idempotent; a retry rotates again.

Permission registry:download_key:manage

Parameters

idpathstring

Response 200 IssuedDownloadKey

View response fields
keyDownloadKey
secretstring

Shown once.

Ready to build?

Create a management key with the permissions your integration needs, or import the OpenAPI file into your client tooling.

Create an API key ↗Download OpenAPI YAML ↗