Pagination
How to page through OpenRelay list endpoints with cursors.
List endpoints that can return many items are cursor-paginated. You request a page, and the response tells you how to fetch the next one.
Request
Pass two optional query parameters:
limit— maximum number of items to return for this page.cursor— an opaque pointer to the next page, taken from the previous response.
curl "https://api.openrelay.inc/v1/orgs/$ORG_ID/clusters?limit=50" \
-H "Authorization: Bearer $OPENRELAY_API_KEY"Response
A page returns an items array and, when more results exist, a nextCursor:
{
"items": [
{ "id": "cl_…", "name": "prod-llama", "status": "running" }
],
"nextCursor": "eyJpZCI6…"
}When nextCursor is absent (or empty), you've reached the last page.
Iterating all pages
Pass the previous nextCursor as the next request's cursor until it's gone:
cursor=""
while :; do
resp=$(curl -fsS \
"https://api.openrelay.inc/v1/orgs/$ORG_ID/clusters?limit=100&cursor=$cursor" \
-H "Authorization: Bearer $OPENRELAY_API_KEY")
echo "$resp" | jq -c '.items[]'
cursor=$(echo "$resp" | jq -r '.nextCursor // empty')
[ -z "$cursor" ] && break
doneasync function* listClusters(orgId: string) {
let cursor: string | undefined;
do {
const url = new URL(`https://api.openrelay.inc/v1/orgs/${orgId}/clusters`);
url.searchParams.set('limit', '100');
if (cursor) url.searchParams.set('cursor', cursor);
const res = await fetch(url, {
headers: { Authorization: `Bearer ${process.env.OPENRELAY_API_KEY}` },
});
const page = await res.json();
yield* page.items;
cursor = page.nextCursor || undefined;
} while (cursor);
}Treat cursors as opaque
A cursor encodes our position in the result set — don't parse, modify, or
construct one. Always use the exact nextCursor value from the previous
response.