{
"id": "page.corvus.getBlock",
"defs": {
"main": {
"type": "query",
"errors": [],
"output": {
"schema": {
"type": "object",
"required": [
"cursor",
"blocks"
],
"properties": {
"blocks": {
"type": "array",
"items": {
"refs": [
"page.corvus.document",
"page.corvus.database"
],
"type": "union",
"closed": false
},
"description": "Materialized snapshots for the requested `blockIds`. Order is not guaranteed to match the input order; blocks the server doesn't have are omitted (no entry, no error). Tree relationships are encoded on the blocks (sequence/register values reference other block-ids); the caller follows those refs with subsequent `getBlock` calls."
},
"cursor": {
"type": "integer",
"description": "The server-assigned sequence number to resume from."
}
}
},
"encoding": "application/json"
},
"parameters": {
"type": "params",
"required": [
"blockIds"
],
"properties": {
"blockIds": {
"type": "array",
"items": {
"type": "string",
"format": "at-uri"
},
"description": "The block ids to materialize. Missing blocks are silently omitted from the output."
},
"includeDids": {
"type": "array",
"items": {
"type": "string",
"format": "did"
},
"description": "Optional allowlist of editor DIDs whose ops the materialization should consider. When omitted, all editors are included."
}
}
},
"description": "Return materialized snapshots for the requested `blockIds` plus the cursor at snapshot time. No transitive walk — only the explicit set is returned."
}
},
"$type": "com.atproto.lexicon.schema",
"lexicon": 1,
"description": "Fetch materialized snapshots of an explicit set of blocks plus the `cursor` at the time of the snapshot. Bootstrap path for clients that don't want to replay history from scratch.\n\n**Explicit set, no descent.** The server returns one snapshot per requested `blockId`. It does NOT walk children, references, or any other graph relation — the caller decides which blocks to materialize. To render a tree, the caller fetches a root, reads child block-ids out of its data, then issues a follow-up `getBlock` for those.\n\n**Bootstrap pattern.** Call `getBlock` for the blocks you care about, then call `page.corvus.getOps` with `cursor: <returned cursor>` and the same `blockIds` to fetch any ops that landed after the snapshot. The applier replays those on top of the snapshot to bring the client to the live tail. The `cursor` returned here is interchangeable with `getOps.cursor` and with `page.corvus.subscribeOps.cursor`.\n\n**Committed state vs pending ops.** The snapshot reflects applied state only; pending ops (suggestions, unresolved review state) are surfaced through the `pendingOps` arrays on the `#register` / `#counter` / `#orSet` / `#seq` primitives in `page.corvus.core`. Clients that need the raw op stream (to compute their own status resolution, or to re-resolve under different review state) should use `getOps` instead of, or in addition to, this query.\n\n**Snapshot freshness.** The server may serve a recently-cached snapshot rather than recomputing every call; in that case the returned `cursor` will lag the server's current high-water and the gap will be filled by the follow-up `getOps` call. Snapshots are never stale in a way that loses ops — they are always a valid materialization at the returned `cursor`."
}