Concepts
Pagination
How cursors, limits and ordering work across the data API.
Cursor paging#
List routes that can return more rows than one page give you next_cursor in the envelope. Pass it back unchanged as cursor to get the next page; it is null on the last page.
# first page
curl -s "https://api.aggre.org/v1/finance/macro/series?limit=100" -H "Authorization: Bearer $AGGRE_API_KEY"
# next page: the previous answer's next_cursor, as it came
curl -s "https://api.aggre.org/v1/finance/macro/series?limit=100&cursor=$NEXT" -H "Authorization: Bearer $AGGRE_API_KEY"Rules:
- A cursor is opaque. Do not parse, build or edit it. A cursor taken from another route, or a garbled one, is
400 invalid_request. - Keep the same filters while paging. (Statute listings tolerate a filter change by continuing after the last id, but do not rely on that elsewhere.)
limitis the page size. Its range is on each route (commonly 1 to 1000, default 100; statutes 1 to 200, default 50; statute provisions 1 to 1000, default 500).- A page never splits one period's versions on the macro routes (
versions=all).
Paging loop:
import os, requests
def pages(url, params):
cursor = None
while True:
q = dict(params, **({"cursor": cursor} if cursor else {}))
r = requests.get(url, params=q, headers={"Authorization": f"Bearer {os.environ['AGGRE_API_KEY']}"}, timeout=30)
r.raise_for_status()
body = r.json()
yield from body["data"]
cursor = body.get("next_cursor")
if not cursor:
returnTime-window paging#
Time series (candles, funding rates, open interest) do not use cursors: next_cursor is always null. Read further with from and to (Unix ms, from inclusive, to exclusive) and order:
order=desc(the default for candles) returns the newest rows first; take the oldesttsyou got and use it as the nextto.order=ascreturns the oldest first; take the newesttsplus one as the nextfrom.
Order#
Each route states its default order and which ones it allows (order=asc|desc). Calendars read forward (asc), series of bars read backward (desc). Name-list searches, statute lists and similar are ordered by an identifier so that paging is stable.
Change feeds#
Where a route has updated_since, rows are ordered by (updated_at, key) ascending and updated_at moves only when the content changed, so updated_since plus the cursor is a change feed: store the newest updated_at you processed and ask for rows since then.
Source: content/concepts/pagination.md