Skip to navigation

Pagination

Every list returns one page and the cursor to reach the next.

List endpoints never return everything. Each returns one page wrapped in the same envelope, plus opaque cursors for moving through the rest.

{
"object": "list",
"url": "/api/v1/gifts",
"has_more": true,
"next_cursor": "AauGZNw_di2MaHLBgeWvyBwU5nXCIKvIBN99nWFDrlfQy0mRyBTj3zOCETV3AKmdePZkZRlz7IwekKAOriAM-Vt8D5FqMqaN3u79VNmfG8_fL-NTygeyP-M",
"previous_cursor": null,
"data": [ ]
}
FieldMeaning
objectAlways "list".
urlThe path this collection was served from.
has_moreWhether another page exists in the direction you are paging.
next_cursorPass as starting_after to move forward. null on the last page.
previous_cursorPass as ending_before to move backward.
total_countHow many records match the request across all pages. Only present when you ask for it with include=total_count.
dataThe resources for this page.

Parameters

ParameterDescription
limitPage size. Defaults to 25.
starting_afterPage forward from this cursor.
ending_beforePage backward from this cursor.
includeOptional extras, comma-separated. total_count is the only supported value.

limit is clamped, not rejected. Values outside 1–100 are silently coerced into range, so limit=5000 returns 100 rather than an error. Do not rely on the number you sent being the number you get.

starting_after and ending_before are mutually exclusive. If you send both, starting_after wins.

Paging forward

Read next_cursor from the response and send it back as starting_after. Stop when has_more is false.

# first page
curl -G https://api.awardspring.com/api/v1/gifts \
-H "X-Spring-API-Key: YOUR_KEY" \
--data-urlencode "limit=25"
# next page
curl -G https://api.awardspring.com/api/v1/gifts \
-H "X-Spring-API-Key: YOUR_KEY" \
--data-urlencode "limit=25" \
--data-urlencode "starting_after=AauGZNw_di2MaHLBgeWvyBwU5nXCIKvIBN99nWFDrlfQy0mRyBTj3zOCETV3AKmdePZkZRlz7IwekKAOriAM-Vt8D5FqMqaN3u79VNmfG8_fL-NTygeyP-M"

Asking for the total

Lists do not count their records unless you ask. Add include=total_count and the response carries total_count, the number of records that match your request across every page, not just this one. Leave it out and the field is not in the response at all.

curl -G https://api.awardspring.com/api/v1/gifts -H "X-Spring-API-Key: YOUR_KEY" --data-urlencode "type=pledge" --data-urlencode "include=total_count"
{
"object": "list",
"url": "/api/v1/gifts",
"has_more": true,
"next_cursor": "AauGZNw_di2MaHLBgeWvyBwU5nXCIKvIBN99nWFDrlfQy0mRyBTj3zOCETV3AKmdePZkZRlz7IwekKAOriAM-Vt8D5FqMqaN3u79VNmfG8_fL-NTygeyP-M",
"previous_cursor": null,
"total_count": 1342,
"data": [ ]
}

The count is taken at the moment of the request. It is worked out fresh each time you ask, so if records are added or removed while you page, a later count can differ from the first. Ask for it on the first page, where it describes the list you are about to walk, rather than on every page.

include is not a filter. Asking for the total on one page and not the next never makes a cursor invalid. Any value other than total_count returns 400 validation_failed.

Send the same filters on every page

This is the part that surprises people. A cursor remembers the filters that produced it. Send q, donor_id, type and similar on the first request, then send them again, with the same values, alongside the cursor on every later page. A later page whose filters differ from the cursor’s, including one that leaves a filter out, returns 400 invalid_cursor rather than quietly paging through a different list.

Filters that take an ID, such as donor_id and award_cycle_id, take the record’s 9-character ID exactly as the API returned it. On the scholarship reporting endpoints award_cycle_id is required on every request, first page or not. A cursor taken while a filter held an older whole-number ID returns 400 invalid_cursor; start again from the first page.

# first page: the filter
curl -G https://api.awardspring.com/api/v1/scholarships/awarded-students \
-H "X-Spring-API-Key: YOUR_KEY" \
--data-urlencode "award_cycle_id=C7RJ3M9QV"
# later pages: the same filter, plus the cursor
curl -G https://api.awardspring.com/api/v1/scholarships/awarded-students \
-H "X-Spring-API-Key: YOUR_KEY" \
--data-urlencode "award_cycle_id=C7RJ3M9QV" \
--data-urlencode "starting_after=AQZ_QUkpFKz7keOS3XOv9NgpNh6sOwfTcenOSpBvYE7MQvGB7hPgWSz30FBcMcW8keay5KUyj9pb3u9j-w7AfjPP1xhCVEM98OP-lJ_Cie_KtYhy1O0gK6tvB3vmGAzbVHRlcH3JGNKRl24"

Cursors are opaque and encrypted

A cursor is an encrypted token bound to your institution and to the filters that produced it. It is not a page number, an offset, or a record id, and it cannot be read: decoding one shows nothing about your data.

Asking for the same page twice returns a different cursor each time. Both work; never compare cursors to decide whether you have seen a page before.

Never build, edit, truncate, or store one for later reuse. A cursor that has been tampered with, has expired, belongs to another institution, or disagrees with the filters on the request returns 400 invalid_cursor.

If you need to resume work later, re-run the first request rather than persisting a cursor.