# CENSUS-CHANGES/1 — the change feed

Public contract for `GET https://api.mcpcensus.com/v1/changes` and the MCP tool `census_changes`. Prices: https://mcpcensus.com/pricing · API keys: https://mcpcensus.com/account

## What it is

An append-only stream of what the Census crons observe, for **every** server (watched or not). Only real transitions are recorded, never "still fine". Retention 90 days. Not a malware scan; PASS is not a sandbox.

| Event | Fired by | Meaning |
|---|---|---|
| `server_new` | nightly registry crawl | first seen in the official registry |
| `remote_down` / `remote_up` | daily probe | hosted endpoint stopped / resumed answering `initialize` |
| `tools_changed` | daily probe | `tools/list` digest changed (count before → after) |
| `health_change` | nightly enrich | health or health_problems flipped |
| `verified_change` | nightly enrich | a leg of the public verified claim moved |
| `security` | nightly enrich | OSV vulnerable flag or count changed |
| `endpoint_moved` | nightly enrich | `remote_url` changed |
| `registry_status` | when observed | official registry status flipped (e.g. active → deprecated) |
| `spec_era_change` | nightly enrich | server moved between MCP spec eras |

## Request

`GET /v1/changes?since=<cursor|RFC 3339>&events=a,b&server_name=<name>&namespace_domain=<domain>&limit=100`

- First call: `since` = an RFC 3339 time, or omit it for the oldest retained event.
- Every response carries `next_cursor` (opaque, `c1.…`), **even when `events` is empty**. Pass it back as `since`. Hourly polling is plenty; the response is cached 60 s.
- `events`: comma-separated names from the table. `server_name`: repeatable, exact canonical names (≤ 50). `namespace_domain`: registrable domain of a DNS-verified namespace. `limit` 1–200.
- Unmetered in v1. Burst guard 20/min per IP or key (429).

## Response

```json
{
  "ok": true, "spec": "CENSUS-CHANGES/1", "as_of": "2026-09-04T11:00:00.000Z",
  "events": [
    { "id": 123, "at": "2026-09-04T09:12:00.000Z", "event": "remote_down", "server_name": "com.example/mcp",
      "namespace_domain": "example.com", "namespace_kind": "domain",
      "summary": "Remote MCP endpoint stopped answering", "detail": { "outcome_kind": "not-found", "http_status": 404 },
      "before": { "alive": 1 }, "after": { "alive": 0 },
      "lookup_url": "https://mcpcensus.com/lookup?q=com.example%2Fmcp", "api_card": "https://api.mcpcensus.com/v1/server?name=com.example%2Fmcp" }
  ],
  "next_cursor": "c1.MTIz", "has_more": false, "retention_days": 90
}
```

MCP: `census_changes({ since, events, server_names, namespace_domain, limit })` returns the same body.

## Use it as a trigger

- A fleet cache or gateway: poll hourly, apply `remote_down` / `endpoint_moved` / `tools_changed` to your allowlist, re-run `census_audit_config` on anything touched.
- A CI schedule: `since` = last run, fail on `security` or `registry_status` for servers in your config.
- A per-server webhook remains the push alternative: `POST /v1/watch` (10 credits) delivers the same events for one server.
