Pagination and filtering
Cursor pagination, sparse fieldsets, and filtering patterns for Fuxam API v4 list endpoints — limit, cursor, fields, and code filters.
List endpoints in the Fuxam API v4 return pages of results inside the shared { data, pagination, meta } envelope. You move through a collection with opaque cursors, optionally shrink each payload with sparse fieldsets, and on supported resources narrow results with filters such as course code.
Why it matters
Institution directories are large. Fetching every user or course in one response is neither reliable nor polite to the shared 1000 requests/min rate budget. Cursor pagination gives stable, efficient pages; sparse fieldsets cut bandwidth; filters let you resolve a single known course without walking the entire catalog.
How it fits
This page builds on the Overview conventions and the first-page call in Getting started. Rate-limit behavior when you paginate aggressively is covered in Errors and idempotency.
Key concepts
| Term | Definition |
|---|---|
| Cursor / keyset pagination | Pages are identified by an opaque cursor over (sortField, id), not by numeric offsets. |
| limit | Page size query parameter: 1–100. Server default applies if omitted. |
| cursor | Opaque token from pagination.next_cursor on the previous page. |
| has_more | When false, you have reached the last page. |
| Sparse fieldset | ?fields= listing the property names you want returned. |
| Filter | Resource-specific query parameters (for example code on courses). |
Cursor pagination reference
| Parameter | Location | Description |
|---|---|---|
limit |
Query | Page size (1–100) |
cursor |
Query | Opaque cursor from the previous page’s pagination.next_cursor |
pagination.next_cursor |
Response | Pass as cursor on the next request when more pages exist |
pagination.has_more |
Response | true if another page is available |
pagination.limit |
Response | Effective page size for this response |
Example list response:
{
"data": [{ "id": "usr_123" }, { "id": "usr_456" }],
"pagination": {
"next_cursor": "eyJpZCI6MTIzfQ==",
"has_more": true,
"limit": 25
},
"meta": {
"requestId": "req_1700000000000_abc123",
"timestamp": "2026-01-15T10:30:00.000Z",
"version": "v4"
}
}
Cursor security
Cursors are HMAC-signed and bound to your institution and integration. Tampered, expired-in-meaning, or foreign cursors return HTTP 400 with code invalid_cursor. Never share cursors across integrations or edit their contents.
How to walk every page
Pseudocode for a full collection sync:
#!/usr/bin/env bash
set -euo pipefail
BASE="https://fuxam.app/api/v4"
CURSOR=""
LIMIT=100
while true; do
if [ -z "$CURSOR" ]; then
URL="${BASE}/users?limit=${LIMIT}"
else
URL="${BASE}/users?limit=${LIMIT}&cursor=${CURSOR}"
fi
RESP=$(curl -sS -u "${CLIENT_ID}:${CLIENT_SECRET}" -H "Accept: application/json" "$URL")
# Process RESP.data in your language of choice, then:
HAS_MORE=$(printf '%s' "$RESP" | jq -r '.pagination.has_more')
CURSOR=$(printf '%s' "$RESP" | jq -r '.pagination.next_cursor // empty')
if [ "$HAS_MORE" != "true" ]; then
break
fi
done
HTTP shape for subsequent pages:
GET /api/v4/users?limit=100&cursor=eyJpZCI6MTIzfQ== HTTP/1.1
Host: fuxam.app
Authorization: Basic <base64(clientId:clientSecret)>
Accept: application/json
Sparse fieldsets
On supported endpoints, request only the fields you need:
GET /api/v4/users?fields=id,email&limit=50 HTTP/1.1
Host: fuxam.app
Authorization: Basic <base64(clientId:clientSecret)>
Accept: application/json
curl -sS \
-u "${CLIENT_ID}:${CLIENT_SECRET}" \
-H "Accept: application/json" \
"https://fuxam.app/api/v4/users?fields=id,email&limit=50"
Benefits:
- Smaller payloads when syncing large directories
- Clearer contracts in typed clients (you document which fields you depend on)
- Less accidental coupling to properties you do not use
Filtering
Filters are resource-specific. A documented and commonly needed example is looking up courses by code, then addressing them by id for subsequent calls (important if you are migrating from v3).
GET /api/v4/courses?code=CS101&limit=25 HTTP/1.1
Host: fuxam.app
Authorization: Basic <base64(clientId:clientSecret)>
Accept: application/json
curl -sS \
-u "${CLIENT_ID}:${CLIENT_SECRET}" \
-H "Accept: application/json" \
"https://fuxam.app/api/v4/courses?code=CS101&limit=25"
Typical follow-up: take data[0].id from the filtered list, then GET /courses/{id} for the full single-resource envelope (and ETag if you will update it). See Recipes for the end-to-end pattern and Courses for the list operation reference.
Courses in Handbook Web are the same entities staff browse in Courses Management and open in the LMS.
Best practices
- Prefer
limit=100for bulk sync jobs; use smaller limits while exploring interactively. - Stop strictly on
has_more === false— do not assume an emptydataarray alone ends the walk without checking pagination. - Combine
fieldswith pagination when you only need ids for a join table. - Respect rate limits when walking many pages; honor
Retry-Afteron429. - Treat cursors as opaque secrets of your integration — do not log them in public channels.
Common pitfalls
| Pitfall | Result | Remedy |
|---|---|---|
Using page / pageSize from v3 |
Unexpected errors or ignored params | Switch to cursor / limit |
| Reusing another integration’s cursor | 400 invalid_cursor |
Start a fresh list with your own credentials |
| Assuming offset stability | Duplicate or missing rows under concurrent writes | Keyset cursors already reduce this; still design syncs for eventual consistency |
| Fetching full objects when you only need ids | Slow syncs, higher rate usage | Use ?fields=id (and other needed keys) |
FAQ
What is the maximum page size?
limit accepts 1–100. Values outside that range should be treated as client errors — stay within the documented range.
Can I jump to page 10?
No. Cursor pagination does not support arbitrary page numbers. Walk forward from the start, or keep a stored cursor from a previous run of the same walk.
Do all list endpoints support the same filters?
No. Filters are per resource. Use code on courses as documented; check each endpoint’s reference page for other query parameters.