// API REFERENCE

The registry API.

BASE URL https://api.policylayer.com

/V0
Public sub-registry
  • Free, no key required
  • Implements the official MCP Registry API
  • Risk data under _meta in every entry
  • Works with any spec-compatible client
/V1
Licensed feed
  • API key on every request
  • Full records: identity, posture, grade, tools, policy
  • Ordered change feed and signed webhooks
  • Nightly snapshot, signed download
// QUICKSTART

Integrate in four steps.

1

Get your key

Buy a licence ($199/month) and the key lands in your inbox, prefixed plr_. Send it on every /v1 request; either header works.

curl https://api.policylayer.com/v1/registry/servers/stripe \
  -H "Authorization: Bearer plr_your_key"

# or
curl https://api.policylayer.com/v1/registry/servers/stripe \
  -H "X-API-Key: plr_your_key"
2

Fetch your first record

One call returns everything we know about a server: verified identity, probed auth posture, the A-to-F grade, every tool with capability flags and a recommended policy.

{
  "slug": "stripe",
  "grade": "F",
  "identity": { "confidence": "verified", … },
  "posture": { "auth": "gated", … },
  "tools": [ { "name": "create_refund", "severity": "Critical" }, … ],
  "policy": { … },
  "version": 14
}
3

Stay current

Poll the change feed with a cursor, or register a webhook and we push. Either way you hear about new tools, grade moves and posture flips within the hour.

# poll
GET /v1/registry/events?after_id=48112&severity=warning

# or push
POST /v1/registry/webhooks
4

Take the whole catalogue

The snapshot endpoint redirects to a signed download of the nightly export: gzipped NDJSON, one record per line. Build your own index from it.

GET /v1/registry/snapshot   # 302, one-hour signed URL
// ENDPOINT INDEX
// AUTHENTICATION

Keys and errors.

Keys authenticate every /v1 request (step 1 above shows both headers). A key is shown once; we store only a hash. A lost or leaked key is rotated, not resent: the old key stops working the moment the new one is issued.

401Missing, malformed, unknown or revoked key.
403Key is valid but the subscription has lapsed or doesn't cover this endpoint.
429Per-key rate limit reached; the Retry-After header says when to come back.
GET/v0/servers?limit=50&cursor=…

List servers

Cursor-paginated list of every published server. Entries carry server (name, packages, remotes, repository) as the MCP Registry spec defines; PolicyLayer's data sits under _meta["com.policylayer/registry"]. metadata.nextCursor is present until the final page.

RESPONSE · 200
{
  "servers": [{
    "server": {
      "name": "com.policylayer/github",
      "title": "GitHub",
      "packages": [{ "registryType": "npm",
        "identifier": "@modelcontextprotocol/server-github" }]
    },
    "_meta": {
      "com.policylayer/registry": {
        "grade": "D",
        "identityConfidence": "verified",
        "toolCount": 86,
        "record": "https://api.policylayer.com/v1/registry/servers/github"
      }
    }
  }],
  "metadata": { "nextCursor": "…", "count": 1 }
}
GET/v0/servers/{name}

Get a server

A single entry, by spec name or bare slug.

BOTH WORK
curl "https://api.policylayer.com/v0/servers/com.policylayer/stripe"
curl "https://api.policylayer.com/v0/servers/stripe"
GET/v1/registry/servers/{slug}

Get a record

The full record for one server (step 2 above shows the shape): identity with confidence and evidence, probed posture, grade, every tool with parameters, capability flags, risk classification and a recommended policy, plus the ten most recent change events.

slugServer slug, e.g. stripe.
versionIncrements only when record content changes. The same version means an identical record.
REQUEST
curl https://api.policylayer.com/v1/registry/servers/stripe \
  -H "X-API-Key: plr_your_key"
GET/v1/registry/servers?after={slug}&limit=100

List records

Full records, keyset-paginated in slug order. A page shorter than limit is the final one.

afterCursor: the nextAfter value from the previous page.
limitUp to 100 records per page.
PAGE THROUGH
GET /v1/registry/servers?limit=100
GET /v1/registry/servers?after=figma&limit=100
GET/v1/registry/events?after_id=0&limit=200

Change events

The ordered change feed. Ids are strictly increasing: persist the last id you processed and resume from it.

after_idResume cursor. Start at 0.
severityFilter to this level and above: info, notice, warning, critical.
limitUp to 200 events per page.

Types include tool_added, tool_removed, tool_reclassified, grade_changed, auth_downgraded, impostor_flagged.

EVENT
{
  "id": 48112,
  "type": "grade_changed",
  "slug": "figma",
  "severity": "warning",
  "from": "C",
  "to": "D"
}
GET/v1/registry/snapshot

Snapshot

Returns a 302 redirect to a one-hour signed download of the nightly catalogue: gzipped NDJSON, one record per line. Add ?format=json to get the URL, size and generation time as JSON instead.

DOWNLOAD
curl -L https://api.policylayer.com/v1/registry/snapshot \
  -H "X-API-Key: plr_your_key" \
  -o registry.ndjson.gz
POST/v1/registry/webhooks

Webhooks

Push instead of poll. The response includes the HMAC secret, shown once. Deliveries start from the moment of registration; for earlier events, use the events endpoint.

Delivery is at-least-once and in order per webhook. Respond with any 2xx to advance the cursor. Failed deliveries are retried on the next cycle; a webhook that fails twenty times in a row is disabled until re-registered.

GET lists your webhooks; DELETE /v1/registry/webhooks/{id} removes one.

REGISTER
{ "url": "https://you.example/hook",
  "minSeverity": "warning" }
VERIFY EVERY DELIVERY
X-PolicyLayer-Signature: sha256=<hex hmac of the raw body>
// CONVENTIONS

How the API behaves.

PaginationKeyset everywhere: an after/cursor token from the previous page, never offsets. Every retry is idempotent.
VersioningRecord versions move only on content change. The same version means an identical record.
HonestyFields we haven't measured are null or absent, never guessed. An unprobed server says so.
Rate limits/v1: per key, per minute; the limit follows your key, not your IP. /v0: per IP. 429s carry Retry-After.
// GET IN TOUCH

Have a question or want to learn more? Send us a message.

Message sent.

We'll get back to you soon.