Skip to content

Data API

Pagination

Page through search results using limit, offset, and search_after on the Parcel Data API.

Every POST /data/{dataset}/search response includes a metadata.total count and supports two pagers: offset for simple shallow paging, and search_after (an opaque keyset cursor) for stable, deep paging past the offset ceiling.


Parameters

ParameterTypeDefaultConstraints
limitinteger251 to 100
offsetinteger00 to 10,000
search_afterstringOpaque keyset cursor from the previous response’s metadata.search_after. Pages forward with no offset ceiling.

Understanding metadata.total

The response metadata object includes:

Metadata fields
{
"metadata": {
"total": 1000,
"total_is_capped": true,
"limit": 25,
"offset": 0,
"search_after": "eyJ2IjoiMjAyNS0xMS0wNCIsImlkIjoiOGExZjNjMmUtMDAwMy00YjdkLTllNWEtMDAwMDAwMDAwMDAzIiwiZiI6Imxhc3Rfc2lnbmFsX2F0IiwibyI6ImRlc2MiLCJlIjoicHJvamVjdCJ9",
"credits": 25
}
}
  • total is a count capped at 1,000. When more than 1,000 records match, total reports 1000 and total_is_capped is true (the true count is higher and unknown).
  • search_after is the cursor for the next page (null on the last page). See Cursor pagination below.
  • credits is the number of records returned in this response (each record costs 1 credit).

Paging through results

Increment offset by limit on each request to walk through result pages.

Page 1 (records 1-25)
curl -X POST https://api.parcelengineering.com/api/v1/data/projects/search \
-H "Authorization: Bearer pcl_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"filters": { "city": { "value": "Boston" } },
"sort": { "field": "last_signal_at", "order": "desc" },
"limit": 25,
"offset": 0
}'
Page 2 (records 26-50)
curl -X POST https://api.parcelengineering.com/api/v1/data/projects/search \
-H "Authorization: Bearer pcl_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"filters": { "city": { "value": "Boston" } },
"sort": { "field": "last_signal_at", "order": "desc" },
"limit": 25,
"offset": 25
}'

Cursor pagination with search_after

offset is capped at 10,000. To page beyond that ceiling, or to page a large result set stably while the underlying data changes, use the search_after cursor instead of offset.

Every search response returns metadata.search_after. Pass that value back as search_after on the next request to fetch the following page. A null cursor means there are no more pages.

Page 1
curl -X POST https://api.parcelengineering.com/api/v1/data/projects/search \
-H "Authorization: Bearer pcl_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"filters": { "city": { "value": "Boston" } },
"sort": { "field": "last_signal_at", "order": "desc" },
"limit": 100
}'
# Response includes: "metadata": { "search_after": "eyJ2IjoiMjAyNS0xMS0wNCIsImlkIjoiOGExZjNjMmUtMDAwMy00YjdkLTllNWEtMDAwMDAwMDAwMDAzIiwiZiI6Imxhc3Rfc2lnbmFsX2F0IiwibyI6ImRlc2MiLCJlIjoicHJvamVjdCJ9", ... }
Page 2 (pass the cursor back)
curl -X POST https://api.parcelengineering.com/api/v1/data/projects/search \
-H "Authorization: Bearer pcl_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"filters": { "city": { "value": "Boston" } },
"sort": { "field": "last_signal_at", "order": "desc" },
"limit": 100,
"search_after": "eyJ2IjoiMjAyNS0xMS0wNCIsImlkIjoiOGExZjNjMmUtMDAwMy00YjdkLTllNWEtMDAwMDAwMDAwMDAzIiwiZiI6Imxhc3Rfc2lnbmFsX2F0IiwibyI6ImRlc2MiLCJlIjoicHJvamVjdCJ9"
}'