--- title: Pagination | Plaza Docs description: 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 List endpoints return a page of results and a `Link` header pointing to the next page: Terminal window ``` 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: 20 X-Has-More: true X-Next-Cursor: 12345678 Link: ; rel="next" ``` When `X-Has-More` is `false` and the `Link` header is absent, you’ve reached the end. ## 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 The `Link` header follows [RFC 8288](https://www.rfc-editor.org/rfc/rfc8288). The URL is in angle brackets, the relation type is after the semicolon. ### TypeScript ``` import Plaza from "@plazafyi/sdk"; const plaza = new Plaza({ apiKey: process.env.PLAZA_API_KEY }); // The SDK handles pagination automatically const 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 ``` import plaza client = plaza.Client(api_key="your-key") # The SDK auto-paginates all_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, )) ``` ### Go ``` 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 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 | 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). |