PackagePass

API reference

Use the control API for package metadata, publishing, grants, tokens, policy, and audit.

The API is JSON over HTTP except for tarball publishing, which uses multipart/form-data. Package installation uses the npm-compatible registry endpoints.

Control API

https://api.preview.packagepass.dev/v1

Registry

https://registry.preview.packagepass.dev/npm/

Authentication

headers
Authorization: Bearer <packagepass-token>
Accept: application/json
X-PackagePass-Tenant: acme

Tenant resolution

Most tenant-scoped endpoints resolve the tenant from tenantId, X-PackagePass-Tenant, or the principal attached to the token.

Response envelope

success
{
  "data": {
    "id": "pkg_...",
    "name": "@acme/payments"
  },
  "requestId": "req_..."
}
error
{
  "error": {
    "code": "forbidden",
    "message": "No matching grant.",
    "details": {}
  },
  "requestId": "req_..."
}

Log requestId

Every response includes a request ID, and the server also returns it as x-request-id. Keep it with failed publish, install, policy, and token operations.

Packages

Create package metadata

Packages must use scoped npm names. Creating a package requires package:publish on the tenant.

POST /v1/packages
curl -X POST "https://api.preview.packagepass.dev/v1/packages" \
  -H "authorization: Bearer $PACKAGEPASS_API_KEY" \
  -H "x-packagepass-tenant: acme" \
  -H "content-type: application/json" \
  -d '{
    "name": "@acme/payments",
    "description": "Customer payments SDK"
  }'

Publish a release tarball

POST /v1/packages/:package/versions
curl -X POST "https://api.preview.packagepass.dev/v1/packages/%40acme%2Fpayments/versions" \
  -H "authorization: Bearer $PACKAGEPASS_API_KEY" \
  -F 'tag=latest' \
  -F 'manifest={"name":"@acme/payments","version":"4.8.0","type":"module"}' \
  -F "tarball=@acme-payments-4.8.0.tgz;type=application/octet-stream"

manifest

JSON package manifest. name must match the route package and version must be semver-compatible.

tarball

The .tgz artifact uploaded as a file part.

tag

Optional dist-tag. Defaults to latest.

Publish a preview tarball

POST /v1/packages/:package/previews
curl -X POST "https://api.preview.packagepass.dev/v1/packages/%40acme%2Fpayments/previews" \
  -H "authorization: Bearer $PACKAGEPASS_API_KEY" \
  -F 'channel=pr-482' \
  -F 'manifest={"name":"@acme/payments","version":"4.8.0","type":"module"}' \
  -F "tarball=@acme-payments-pr-482.tgz;type=application/octet-stream"

Preview publishes generate or accept a preview version, set the dist-tag preview-<channel>, and return install commands.

Access

Create a grant

Grants are the authorization records used by the API and registry. Creating grants requires grant:manage on the target resource.

POST /v1/grants
curl -X POST "https://api.preview.packagepass.dev/v1/grants" \
  -H "authorization: Bearer $PACKAGEPASS_API_KEY" \
  -H "x-packagepass-tenant: acme" \
  -H "content-type: application/json" \
  -d '{
    "subject": { "type": "customer", "slug": "globex" },
    "resource": { "type": "package", "name": "@acme/payments" },
    "actions": ["package:install"],
    "conditions": {
      "expiresAt": "2026-05-26T00:00:00.000Z"
    }
  }'

Common schemas

SchemaShape
SubjectRef{ "type": "user", "email": "alice@example.com" }, { "type": "customer", "slug": "globex" }, { "type": "agent", "slug": "release", "kind": "ci" }
ResourceRef{ "type": "tenant", "slug": "acme" }, { "type": "scope", "name": "@acme" }, { "type": "package", "name": "@acme/payments" }, { "type": "package_version", "name": "@acme/payments", "version": "4.8.0" }
GrantInputtenantId, subject, resource, actions, and optional conditions. The current policy engine enforces expiresAt; other condition fields are stored as metadata.
TokenCreateInputtenantId, name, subject, optional resources with actions, and optional expiresAt.
RegistryPackageid, tenantId, scopeId, name, slug, description, readme, distTags, archivedAt, createdAt, and updatedAt.
RegistryVersionid, tenantId, packageId, packageName, version, kind, status, manifest, tarball, provenance, deprecatedMessage, and createdAt.

Create an install token

POST /v1/tokens/install
curl -X POST "https://api.preview.packagepass.dev/v1/tokens/install" \
  -H "authorization: Bearer $PACKAGEPASS_API_KEY" \
  -H "x-packagepass-tenant: acme" \
  -H "content-type: application/json" \
  -d '{
    "name": "globex payments install",
    "subject": { "type": "customer", "slug": "globex" },
    "resources": [{
      "type": "package",
      "name": "@acme/payments",
      "actions": ["package:install"]
    }],
    "expiresAt": "2026-05-26T00:00:00.000Z"
  }'

Endpoint reference

Identity

MethodPathPurpose
GET/v1/meReturn the authenticated principal.

Tenants and scopes

MethodPathPurpose
POST/v1/tenantsCreate a tenant.
GET/v1/tenantsList tenants.
POST/v1/scopesCreate a scope such as @acme.
GET/v1/scopesList scopes for the active tenant.

Packages

MethodPathPurpose
POST/v1/packagesCreate package metadata.
GET/v1/packagesList packages.
GET/v1/packages/:packageRead package metadata.
PATCH/v1/packages/:packageUpdate description or readme.
POST/v1/packages/:package/archiveArchive a package.

Versions and previews

MethodPathPurpose
POST/v1/packages/:package/versionsPublish a release tarball with multipart/form-data.
GET/v1/packages/:package/versionsList versions.
GET/v1/packages/:package/versions/:versionRead one version.
POST/v1/packages/:package/versions/:version/deprecateDeprecate a version.
POST/v1/packages/:package/versions/:version/yankYank a version.
POST/v1/packages/:package/previewsPublish a preview tarball to preview-<channel>.
GET/v1/packages/:package/previewsList preview versions.

Dist-tags

MethodPathPurpose
GET/v1/packages/:package/dist-tagsRead dist-tags.
PUT/v1/packages/:package/dist-tags/:tagPoint a tag at a version.
DELETE/v1/packages/:package/dist-tags/:tagRemove a tag.

Access control

MethodPathPurpose
POST/v1/grantsCreate a grant.
GET/v1/grantsList grants.
DELETE/v1/grants/:grantIdRevoke a grant.
POST/v1/policy/explainExplain an authorization decision.

Subjects and tokens

MethodPathPurpose
POST/v1/customersCreate a customer subject.
GET/v1/customersList customer subjects.
POST/v1/agentsCreate an agent subject.
GET/v1/agentsList agent subjects.
GET/v1/agents/:agentRead an agent subject.
PATCH/v1/agents/:agentUpdate an agent subject.
DELETE/v1/agents/:agentDelete an agent and clean up direct access, tokens, and memberships.
POST/v1/groupsCreate a group subject.
GET/v1/groupsList group subjects.
GET/v1/groups/:groupRead a group subject and its members.
PATCH/v1/groups/:groupUpdate a group subject.
DELETE/v1/groups/:groupDelete a group and clean up direct access, tokens, and memberships.
POST/v1/tokens/apiMint an API token.
POST/v1/tokens/installMint an install token.
POST/v1/tokens/ci/exchangeExchange a CI identity token.
GET/v1/tokensList tokens.
DELETE/v1/tokens/:tokenIdRevoke a token.

Utilities

MethodPathPurpose
POST/v1/install-configGenerate .npmrc or bunfig.toml content.
GET/v1/audit-eventsList audit events.
POST/v1/validate/packageValidate package.json against PackagePass policy.

Registry endpoints

EndpointPurpose
GET /npm/-/pingRegistry health check.
GET /npm/-/whoamiReturn the package-install principal for the current token.
GET /npm/:encodedPackageReturn an npm packument for an authorized package.
GET /npm/:encodedPackage/-/:tarballDownload an authorized tarball.
HEAD /npm/:encodedPackage/-/:tarballCheck tarball availability without downloading it.

Registry package and tarball requests require package:install. Unauthorized packages and tarballs are returned as 404 to avoid leaking package names.

Package policy

Required

Scoped package name, semver-compatible version, and a manifest name that matches the route package.

Blocked by default

Lifecycle scripts such as postinstall, binaries, and bundled dependencies are blocked for generated TypeScript libraries.

Action names

package:read
package:install
package:publish
package:deprecate
package:yank
package:manage_dist_tags
grant:manage
token:mint
audit:read