# page.corvus.getOps

> Published by [corvus.page](https://lexicon.garden/identity/did:plc:3qc4cbzcriye72qqqodeda26)

✓ This is the authoritative definition for this NSID.

## Description

Paginated forward read of an op log scoped to an explicit block set. Pull-based alternative to opening a `page.corvus.subscribeOps` WebSocket at `cursor: 0` — same op shape, same cursor semantics, just delivered as a query page instead of a live tail. Each entry is a `page.corvus.subscribeOps#op` so live and historical paths feed the same applier.

Like `subscribeOps`, this query does NOT walk graph relations. Callers fetch ops for the blocks they care about and follow refs explicitly with subsequent calls.

## Links

- [View on Lexicon Garden](https://lexicon.garden/lexicon/did:plc:3qc4cbzcriye72qqqodeda26/page.corvus.getOps)
- [Documentation](https://lexicon.garden/lexicon/did:plc:3qc4cbzcriye72qqqodeda26/page.corvus.getOps/docs)
- [Examples](https://lexicon.garden/lexicon/did:plc:3qc4cbzcriye72qqqodeda26/page.corvus.getOps/examples)

## Definitions

### `page.corvus.getOps`

**Type**: `query`

Read ops for the requested `blockIds` in forward cursor order, strictly after `cursor`.

#### Parameters

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `limit` | `integer` | No | Maximum number of ops to return in this page. |
| `cursor` | `integer` | No | Server-assigned cursor (exclusive) to resume from. Omitted = start from cursor 0 (every op the server has for the requested blocks). Same semantic as `page.corvus.subscribeOps#main.cursor`. |
| `blockIds` | `array` | Yes | The explicit set of block ids to read ops for. No transitive walk — only ops whose `blockId` is in this set are returned. |
| `includeDids` | `array` | No | The dids of the users to include. |

#### Output

**Encoding**: `application/json`

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `ops` | `array` | Yes | Ops for the requested blocks with cursor strictly greater than the input `cursor`, in ascending cursor order. Up to `limit` entries. Shape is identical to a live `page.corvus.subscribeOps#op` frame. |
| `cursor` | `integer` | No | Cursor of the last op in `ops`. Pass this as `cursor` on the next call to continue paginating. Omitted when `ops` is empty (caller is caught up to the server's high-water for these blocks). |

#### Errors

- **InvalidCursor**: The supplied cursor is malformed or beyond the server's current high-water.

## Raw Schema

```json
{
  "id": "page.corvus.getOps",
  "defs": {
    "main": {
      "type": "query",
      "errors": [
        {
          "name": "InvalidCursor",
          "description": "The supplied cursor is malformed or beyond the server's current high-water."
        }
      ],
      "output": {
        "schema": {
          "type": "object",
          "required": [
            "ops"
          ],
          "properties": {
            "ops": {
              "type": "array",
              "items": {
                "ref": "page.corvus.subscribeOps#op",
                "type": "ref"
              },
              "description": "Ops for the requested blocks with cursor strictly greater than the input `cursor`, in ascending cursor order. Up to `limit` entries. Shape is identical to a live `page.corvus.subscribeOps#op` frame."
            },
            "cursor": {
              "type": "integer",
              "description": "Cursor of the last op in `ops`. Pass this as `cursor` on the next call to continue paginating. Omitted when `ops` is empty (caller is caught up to the server's high-water for these blocks)."
            }
          }
        },
        "encoding": "application/json"
      },
      "parameters": {
        "type": "params",
        "required": [
          "blockIds"
        ],
        "properties": {
          "limit": {
            "type": "integer",
            "default": 500,
            "maximum": 1000,
            "minimum": 1,
            "description": "Maximum number of ops to return in this page."
          },
          "cursor": {
            "type": "integer",
            "description": "Server-assigned cursor (exclusive) to resume from. Omitted = start from cursor 0 (every op the server has for the requested blocks). Same semantic as `page.corvus.subscribeOps#main.cursor`."
          },
          "blockIds": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "at-uri"
            },
            "description": "The explicit set of block ids to read ops for. No transitive walk — only ops whose `blockId` is in this set are returned."
          },
          "includeDids": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "did"
            },
            "description": "The dids of the users to include."
          }
        }
      },
      "description": "Read ops for the requested `blockIds` in forward cursor order, strictly after `cursor`."
    }
  },
  "$type": "com.atproto.lexicon.schema",
  "lexicon": 1,
  "description": "Paginated forward read of an op log scoped to an explicit block set. Pull-based alternative to opening a `page.corvus.subscribeOps` WebSocket at `cursor: 0` — same op shape, same cursor semantics, just delivered as a query page instead of a live tail. Each entry is a `page.corvus.subscribeOps#op` so live and historical paths feed the same applier.\n\nLike `subscribeOps`, this query does NOT walk graph relations. Callers fetch ops for the blocks they care about and follow refs explicitly with subsequent calls."
}
```
