---
title: "Public drift ledger: contract changes the crawler observed, paged"
method: GET
path: "/api/v1/ledger"
---

# Public drift ledger: contract changes the crawler observed, paged

`GET /api/v1/ledger`

## Request

- Base URL: `https://mcpindex.ai`
- URL: `https://mcpindex.ai/api/v1/ledger`
- Auth: none declared

Contract diffs listed by fingerprint (keyed hashes of public registry names under a published key; recomputable, not anonymous) - a contract-diff record, not a safety verdict. Schema mcpindex.drift.ledger/4. One section per request: events (tool contract changes), context_events (server instructions and prompt metadata) or fleet_events (publisher-wide changes, counted once). When ledger_schema is mcpindex.drift.ledger/3, events omits tools whose only change was part of a publisher-wide change; look those up with /api/v1/drift/any. events and context_events pages hold up to 1,000 rows, newest first; fleet_events pages are packed by size. With no parameters this returns page 0 of events. To read a whole section, request ?section=<name> and follow next_cursor until it is null. A cursor stays in the generation it was issued for, so every page of one walk comes from the same hourly publish; a superseded generation stays readable for at least an hour after the next publish, then its cursors answer 410. The /3 single-response dump is retired.

## Query parameters

- `section` 'events' | 'context_events' | 'fleet_events'
- `cursor` string

## Response `200`

One page of one section.

- object
  - `schema` 'mcpindex.drift.ledger/4', required
  - `generated_at` string, required: When the latest index was published. The same on every page.
  - `generation` string, required: The generation the items belong to. A cursor keeps it, so every page of one walk carries the same value.
  - `ledger_schema` 'mcpindex.drift.ledger/2' | 'mcpindex.drift.ledger/3', required: The row semantics the drain built. Under /3, publisher-wide changes are counted once in fleet_events.
  - `framing` string, required
  - `stat` object, required: Headline counts from the latest published generation.
  - `counts` object, required: Row counts from the latest published generation.
  - `section` 'events' | 'context_events' | 'fleet_events', required
  - `page` integer, required: Zero-based page number.
  - `pages` integer, required: Page count for this section in this generation.
  - `items` object[], required: Rows of the requested section, validated: malformed event and context rows are dropped and free fields bounded, so a page can hold fewer rows than counts suggests.
  - `next_cursor` string, nullable, required: Pass as ?cursor= for the next page; null on the last page.

## Other responses

- `400`: invalid_section, invalid_cursor or section_cursor_mismatch.
- `410`: cursor_expired: that generation's pages are gone. restart is the path that starts the section again.
- `429`: Rate limited; see retry-after.
- `503`: The ledger is not published right now (missing, stale or malformed). No rows are served.

---

[API](https://skmtc.dev/mcpindex/apis/mcpindex-ai-public-api.md) · [All operations](https://skmtc.dev/mcpindex/apis/mcpindex-ai-public-api/llms.txt) · [OpenAPI document](https://skmtc.dev/mcpindex/apis/mcpindex-ai-public-api/revisions/153445d5c87f?raw)
