Buyers

Composer endpoints

What the marketplace serves over /packages.json, /p2/*.json, and /dist/*: the auth shape, the status codes, what is cached and how, and how to debug a misbehaving install.

What this page is for

If you just want to install a package, see Composer setup. This page is the technical reference for what the endpoints actually do - useful when you're debugging a CI run, building a wrapper script, or trying to understand why a buyer sees one set of versions and you see another.

Endpoint map

GET /packages.json
Composer V2 root metadata. Returns the metadata-url template and the list of available packages your token is entitled to. Required by Composer before any /p2/* fetch.
GET /p2/{vendor}/{package}.json
Per-package version metadata. Lists every version your token can install, with composer.json-shape entries. Filtered by your active licence (and, for subscriptions, by the date your access window closes).
GET /dist/{vendor}/{package}/{version}.zip
The actual archive. Token auth, package entitlement, and the version filter are re-checked on every request, so revoking a token blocks subsequent downloads immediately. A request already mid-stream when you revoke continues to its end; the next request from that token fails.
POST /composer/downloads
Composer's notify-batch hook. Composer calls this after a successful install with the list of packages it just pulled; the platform records IP, user-agent, and token id for download analytics. Idempotent and best-effort: a 5xx here doesn't block the install.

Authentication

All four endpoints use HTTP Basic with project-scoped credentials:

  • Username: the token's public_key (a random hex string).
  • Password: the token's private_key (a random hex string, revealed inline when you create the token; also available via the Download auth.json link on the token row).

Tokens are project-scoped: a token created in your "production" project sees only the licences activated against that project. Cross-project access requires either activating the licence against the other project, or creating a token in the other project - see API tokens.

A typical auth.json (the host matches your Packagento install):

{
  "http-basic": {
    "packagento.com": {
      "username": "<public_key>",
      "password": "<private_key>"
    }
  }
}

Status codes you'll see

200 OK
Normal response with body.
304 Not Modified
Conditional GET hit on /packages.json or /p2/*.json - Composer sent If-None-Match and the ETag still matches. Body is empty by HTTP spec.
401 Unauthorized
Token missing, malformed, revoked, or password mismatch. The response carries a WWW-Authenticate: Basic header. Either edit auth.json directly or run composer config --global http-basic.<host> <public_key> <private_key> to set the credentials.
404 Not Found
Package or version is not visible to your token. This is deliberately the same response as a non-existent package - we don't want to disclose the existence of packages a token isn't entitled to. If you expect to see a package, check the licence is activated against this project.
5xx
Genuine server error. Composer retries on its own schedule; if the retry window expires, your install fails. Get in touch through our contact form if it persists.

Caching and ETags

Composer caches metadata aggressively. The platform serves an ETag on /packages.json and /p2/*.json; on every subsequent request Composer sends If-None-Match and the platform returns 304 if the manifest hasn't changed. When you publish a new tag, the etag invalidates immediately - buyers don't need to clear their Composer cache. The /dist/* endpoint isn't etag'd (the archive's identity is the URL); browsers and proxies should treat archives as immutable.

No rate limits - but be reasonable

There is no per-token request quota at this time, and Composer is not throttled. That said, please:

  • Don't poll /p2/*.json on a tight loop. Composer's ETag handling is enough - you should see 304s for repeated reads.
  • Don't parallelise /dist/* downloads beyond what Composer does natively (it already runs concurrent downloads).
  • Use one token per CI runner; don't share a single token across many simultaneous builds.

If the platform later introduces explicit limits (e.g. abuse mitigation), they will be communicated to API-token holders by email before they take effect.

Debugging an install

Composer's -v and -vvv flags print the HTTP requests it makes. The most useful diagnostic is:

composer require -vvv vendor/package:^1.4

Look for:

  • 401 from /packages.json: the token isn't reaching the platform. Check auth.json lives where Composer expects (project root or ~/.composer/) and the host key matches your repository hostname exactly.
  • 404 from /p2/vendor/package.json: package isn't in your token's entitlement set - usually the licence is on a different project.
  • 200 metadata, 401 on /dist/: shouldn't happen - both endpoints share the same auth path. If you see this, get in touch through our contact form with the request and response headers.