List endpoints in the Rho API return results in pages using opaque cursor-based pagination. You ask for a page size, the response includes the items plus a cursor to the next page, and you follow that cursor to fetch each subsequent page.
Cursors are stable across changes to the underlying data: new items inserted while you are iterating will not shift existing pages or cause items to be skipped or duplicated.
Every list endpoint accepts the same two pagination parameters as query string values:
| Parameter | Type | Notes |
|---|---|---|
page_size | integer | How many items to return. Each endpoint defines its own minimum, maximum, and default - see the API Reference. Values outside the allowed range return 400 Bad Request. |
page_token | string | Opaque cursor returned as next_page_token by a previous response. Omit to fetch the first page. |
Cursors are opaque - pass back exactly the string you received.
A token returned by one endpoint is only valid for that same endpoint with the same filters and sort order. Using a cursor with changed filters or sorting will result in 400 Bad Request.
Every paginated response wraps the items in a top-level array and includes a page object:
{
"transactions": [
{ "id": "…", "amount": { "amount": 1299, "currency": "USD" }, "…": "…" },
{ "id": "…", "amount": { "amount": 4500, "currency": "USD" }, "…": "…" }
],
"page": {
"next_page_token": "eyJvIjoxMDAsImQiOiIyMDI2LTA1LTE0In0"
}
}The array key matches the resource being listed (accounts, transactions, …). The page.next_page_token field is either:
- A string - pass it as
page_tokenon the next request to fetch the following page. null- you have reached the last page; there is nothing more to fetch.
The canonical iteration pattern is a loop that stops when the cursor goes null. In Python:
import os
import requests
def list_all_transactions(account_id: str):
token = os.environ["RHO_API_TOKEN"]
page_token = None
while True:
params = {"account_id": account_id, "page_size": 100}
if page_token is not None:
params["page_token"] = page_token
resp = requests.get(
"https://rhoapi.rho.co/api/v1/transactions",
params=params,
headers={"Authorization": f"Bearer {token}"},
timeout=30,
)
resp.raise_for_status()
body = resp.json()
yield from body["transactions"]
page_token = body["page"]["next_page_token"]
if page_token is None:
returnEquivalent with curl:
# First page
curl "https://rhoapi.rho.co/api/v1/transactions?page_size=100" \
-H "Authorization: Bearer $RHO_API_TOKEN"
# Subsequent page - pass the next_page_token from the previous response
curl "https://rhoapi.rho.co/api/v1/transactions?page_size=100&page_token=eyJvIjoxMDAsImQiOiIyMDI2LTA1LTE0In0" \
-H "Authorization: Bearer $RHO_API_TOKEN"- Modifying filters between pages. A
page_tokenis bound to the query it was issued for. Changeaccount_id,status,sort_by, etc., and you must start over from the first page. - Storing cursors long-term. Cursors are designed for live iteration, not for bookmarks. Their format and lifetime are not part of the API contract and may change without notice.