Pagination
Navigate large result sets with cursor-based pagination and Link headers.
Plaza supports cursor-based and offset-based pagination. Cursor mode uses osm_id for efficient keyset pagination. Offset mode uses traditional LIMIT/OFFSET. If both are provided, cursor takes precedence.
How it works
Section titled “How it works”List endpoints return a page of results and a Link header pointing to the next page:
curl -i -H "x-api-key: $PLAZA_API_KEY" \ "https://plaza.fyi/api/v1/features?around=48.85,2.34&radius=1000&tags[amenity]=cafe&limit=20"Response headers:
X-Limit: 20X-Has-More: trueX-Next-Cursor: 12345678Link: </api/v1/features?around=48.85%2C2.34&radius=1000&tags[amenity]=cafe&limit=20&cursor=12345678>; rel="next"When X-Has-More is false and the Link header is absent, you’ve reached the end.
Parameters
Section titled “Parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
limit | int | 20 | Results per page. Min 1, max 1,000. |
cursor | string | — | Cursor from a previous Link header. |
offset | int | 0 | Offset for offset-based pagination. |
Parsing the Link header
Section titled “Parsing the Link header”The Link header follows RFC 8288. The URL is in angle brackets, the relation type is after the semicolon.
TypeScript
Section titled “TypeScript”import Plaza from "@plazafyi/sdk";
const plaza = new Plaza({ apiKey: process.env.PLAZA_API_KEY });
// The SDK handles pagination automaticallyconst allCafes = [];for await (const page of plaza.nodes.list({ within: { type: "Polygon", coordinates: [[[2.2, 48.8], [2.5, 48.8], [2.5, 48.9], [2.2, 48.9], [2.2, 48.8]]], }, tags: "amenity:cafe", limit: 50,})) { allCafes.push(...page.features);}console.log(`Found ${allCafes.length} cafes`);Python
Section titled “Python”import plaza
client = plaza.Client(api_key="your-key")
# The SDK auto-paginatesall_cafes = list(client.nodes.list( within={ "type": "Polygon", "coordinates": [[[2.2, 48.8], [2.5, 48.8], [2.5, 48.9], [2.2, 48.9], [2.2, 48.8]]], }, tags="amenity:cafe", limit=50,))package main
import ( "context" "fmt" "github.com/plazafyi/plaza-go")
func main() { client := plaza.NewClient(plaza.WithAPIKey("your-key"))
iter := client.Nodes.List(context.Background(), &plaza.NodeListParams{ Within: &plaza.Geometry{ Type: "Polygon", Coordinates: [][][2]float64{{{2.2, 48.8}, {2.5, 48.8}, {2.5, 48.9}, {2.2, 48.9}, {2.2, 48.8}}}, }, Tags: plaza.String("amenity:cafe"), Limit: plaza.Int(50), })
var count int for iter.Next() { page := iter.Current() count += len(page.Features) } if err := iter.Err(); err != nil { panic(err) } fmt.Printf("Found %d cafes\n", count)}Cursor stability
Section titled “Cursor stability”Cursors are stable until the next data update (daily for OSM, varies for other datasets). After an update, old cursors return 400 — start from the first page.
This only matters for long-running pagination jobs. A few thousand results will finish well before the next update.
Response headers
Section titled “Response headers”| Header | Description |
|---|---|
X-Limit | The page size used for this request. |
X-Has-More | true if there are more results, false if this is the last page. |
X-Next-Cursor | The cursor value for the next page (cursor mode only). |
X-Next-Offset | The offset for the next page (offset mode only). |
Link | RFC 8288 link to the next page (absent on the last page). |