Appearance
Pagination
Every list endpoint returns the same envelope:
json
{
"object": "list",
"has_more": true,
"data": [ /* … */ ]
}| Field | Meaning |
|---|---|
object | Always "list". |
has_more | Whether more records exist beyond this page. |
data | The records, newest first. |
Parameters
| Parameter | Default | Notes |
|---|---|---|
limit | 20 | Between 1 and 100. |
after | — | An object's id. Returns the records after it (older). |
before | — | An object's id. Returns the records before it (newer). |
after and before are cursors, not offsets: you pass the id of a record, not a page number. The record you name is not included in the result.
Passing both after and before is an error (validation_error), as is a limit outside 1–100 or a cursor we don't recognise (invalid_parameter) — rather than quietly returning an empty page and letting you conclude you have no data.
Walking a list
Take the last id of a page and pass it as after:
bash
# first page
curl "https://api.sendgrail.com/v1/emails?limit=50" \
-H "Authorization: Bearer $SENDGRAIL_API_KEY"
# next page — the id of the last record above
curl "https://api.sendgrail.com/v1/emails?limit=50&after=4ef9a417-02e9-4d39-ad75-9611e0fcc33c" \
-H "Authorization: Bearer $SENDGRAIL_API_KEY"js
let after = undefined;
do {
const url = new URL('https://api.sendgrail.com/v1/emails');
url.searchParams.set('limit', '50');
if (after) url.searchParams.set('after', after);
const res = await fetch(url, {
headers: { Authorization: `Bearer ${process.env.SENDGRAIL_API_KEY}` },
});
const page = await res.json();
for (const email of page.data) {
// …
}
after = page.has_more ? page.data.at(-1).id : undefined;
} while (after);Why cursors, not pages
A page number has to be counted from the start of the list every time you ask for it, which gets slower the deeper you go — and on a list that is still growing (emails, logs), the ground moves under you: a record arriving between two requests shifts everything down by one, so page 2 repeats a row page 1 already gave you.
A cursor says "carry on from this record". It costs the same whether you're on the first page or the thousandth, and nothing you've already seen can reappear.