Every list (GET /api/v2/funding_rounds, /funding_applications, /contracts, /registration_entities, /milestones) answers a bare JSON array of records in ascending id order, at most 50 at a time. There is no page number and no cursor: you page by id.
The parameters
| Parameter | What it does |
|---|---|
limit | Records per page. Default 50, at most 50: a larger value is read as 50. Not an integer, or below 1, answers 400 invalid_request with limit is invalid. |
gt | Only records whose id is greater than this. Pass the last id you received to read the next page. |
lt | Only records whose id is less than this. |
Each parameter is an integer, sent once. A parameter that is not an integer, or is sent twice, answers 400 invalid_request naming it. A gt or lt that no id can meet is an empty page, not an error. A parameter a route does not document is ignored, except a filters[…] key the milestones list does not know, which is 400.
Read every page
- Ask for the first page with no
gt. - Keep the
idof the last record on the page. - Ask again with
gtset to that id. - Stop when a page holds fewer records than the
limit: there are no more.
curl "https://your-org.backed.giving/api/v2/funding_applications?limit=50" -H "Authorization: Bearer $BACKED_TOKEN"
curl "https://your-org.backed.giving/api/v2/funding_applications?limit=50>=1287" -H "Authorization: Bearer $BACKED_TOKEN"async function* everyRecord(path, token) {
let after = null;
for (;;) {
const query = new URLSearchParams({ limit: '50' });
if (after !== null) query.set('gt', String(after));
const response = await fetch(`https://your-org.backed.giving${path}?${query}`, {
headers: { Authorization: `Bearer ${token}` },
});
if (!response.ok) throw new Error(`${path}: ${response.status}`);
const page = await response.json();
yield* page;
if (page.length < 50) return;
after = page[page.length - 1].id;
}
}
for await (const application of everyRecord('/api/v2/funding_applications', token)) {
console.log(application.id, application.state);
}Filters, such as submitted=1 on funding applications or filters[ids][] on milestones, narrow the list before it is paged: keep sending them with every page.
The OData reporting feed pages differently: up to 1000 rows a page, each ending with `@odata.nextLink` while more remain. See Power BI.
