List endpoints return one page at a time and hand you a cursor to fetch the next. There is no offset/page-number paging — cursors are stable under inserts, so you never skip or double-read a row while paging a live feed. Two cursor conventions exist in the API, depending on the endpoint:Documentation Index
Fetch the complete documentation index at: https://docs.alterscope.org/llms.txt
Use this file to discover all available pages before exploring further.
- Envelope cursor — most list endpoints (e.g.
GET /v2/yield/opportunities) return paging state insidemeta: an opaquecursorplus ahas_moreboolean. - Replay cursor — the event replay endpoint (
GET /v2/events/replay) walks forward by event ID and signals the end with an emptynext_cursor.
Envelope cursor (meta.cursor + meta.has_more)
GET /v2/yield/opportunities is the reference example. The response wraps its rows in the standard envelope and carries paging state in meta:
| Field | Meaning |
|---|---|
meta.cursor | Opaque cursor for the next page. Pass it back as page[cursor]. |
meta.has_more | true while more pages remain; false on the last page. |
meta.limit | The page size that was applied. |
meta.total | Total rows matching your filters across all pages. |
Page size
Set the page size withpage[limit]. For /v2/yield/opportunities the default is 50 and the maximum is 200; a value above the maximum is clamped down rather than rejected. Page-size defaults and caps vary by endpoint — the Endpoints group in the sidebar documents each one. Request the next page by passing page[cursor] set to the previous response’s meta.cursor.
Other list families that use the envelope cursor (for example point-in-time snapshots) expose the same
cursor / has_more pair in meta. The field names are identical; only the per-endpoint limit default and cap differ.Loop until has_more is false
Keep fetching while meta.has_more is true, feeding meta.cursor back as page[cursor] each time:
Each page counts as one request against your rate limit. Use the largest
limit the endpoint allows to minimize round-trips, and watch X-RateLimit-Remaining to throttle before you hit 429.Replay cursor (next_cursor)
GET /v2/events/replay recovers events you missed during a WebSocket disconnect. It is cursor-based on event ID — not timestamp ranges. Walk forward by passing the last event’s ID as since_event_id, and stop when next_cursor comes back empty.
| Parameter | Default | Notes |
|---|---|---|
since_event_id | — | A ULID event ID. The walk returns events after this one. Omit it for the first page. A non-ULID value returns 400 INVALID_CURSOR. |
limit | 100 | Page size, capped at 1000. Out-of-range or non-numeric values fall back to the default. |
type | — | Optional single event-type filter (e.g. peg.depeg.start). An unknown type returns 400 INVALID_EVENT_TYPE. |
subject_id | — | Optional filter to a single subject (e.g. a specific vault or feed). |
410 REPLAY_WINDOW_EXPIRED, and the Free tier — which has no replay window — returns 404 REPLAY_NOT_AVAILABLE. Per-tier replay windows are in Rate limits & tiers.
The response keeps its fields at the top level (it is not wrapped under data/meta):
Loop until next_cursor is empty
Pass next_cursor back as since_event_id until it comes back empty:
Replay is for recovery, not for live streaming. For ongoing updates, subscribe over WebSockets or webhooks and use replay only to backfill the gap after a reconnect.
Filtering
Filters narrow a list before it’s paged. The set below is whatGET /v2/yield/opportunities accepts — other endpoints expose their own filters, documented in the Endpoints group. Filter parameters use the filter[...] bracket form; comma-separate values for the multi-value filters.
| Parameter | Example | Effect |
|---|---|---|
filter[venue] | aave,morpho | Restrict to one or more protocols. |
filter[chain] | ethereum,stellar | Restrict to one or more chains. |
filter[asset] | ETH,USDC | Restrict to opportunities involving these assets. |
filter[strategy] | lending,vault_managed | Restrict to one or more strategy types. |
filter[riskBand] | 1,2 | Restrict to specific risk bands. |
filter[maxRiskBand] | 2 | Cap the risk band (anything above is excluded). |
filter[tier] | 1,2 | Restrict to data-tier 1, 2, or 3. |
filter[directionality] | market_neutral | Restrict by directionality. |
filter[minApy] / filter[maxApy] | 5 / 50 | Bound net APY (percent). |
filter[minLiquidityScore] | 60 | Minimum liquidity score. |
filter[minTvl] | 1000000 | Minimum TVL in USD. |
search | ETH | Full-text search across name and asset. |
Filters apply before pagination, so
meta.total reflects the filtered set, not the whole catalog. Apply the same filters on every page of a paging loop — changing them mid-loop invalidates the cursor.Sorting
GET /v2/yield/opportunities accepts a single sort parameter. Prefix the field with - for descending order. The default sort is -tvlUsd (largest TVL first).
sort (and filters) across the loop.
See also
API reference overview
Base URL, auth, and the response envelope.
Rate limits & tiers
Per-tier request rates, quotas, and replay windows.
Errors
The standard error envelope and status codes.
Webhooks
Push delivery for live events.