Overview
Pagination
Handle paginated responses from the Figma REST API efficiently.
Some Figma API endpoints return paginated responses when the result set is large. This guide explains how to work with cursor-based pagination.
How Pagination Works
Paginated endpoints include a pagination object in the response with a cursor for the next page:
{
"meta": {
"components": [
{ "key": "abc123", "name": "Button" },
{ "key": "def456", "name": "Input" }
]
},
"pagination": {
"cursor": "eyJpZCI6IjEyMzQ1In0=",
"page_size": 30
}
}
Fetching All Pages
Pass the cursor as a query parameter to get the next page. When cursor is null or absent, you’ve reached the end.
async function fetchAllComponents(fileKey: string, token: string) {
const components = [];
let cursor: string | undefined;
do {
const url = new URL(`https://api.figma.com/v1/files/${fileKey}/components`);
if (cursor) url.searchParams.set("cursor", cursor);
const response = await fetch(url.toString(), {
headers: { "X-Figma-Token": token },
});
const data = await response.json();
components.push(...data.meta.components);
cursor = data.pagination?.cursor ?? undefined;
} while (cursor);
return components;
}
Pagination Parameters
| Parameter | Type | Description |
|---|---|---|
cursor | string | Opaque cursor from the previous response |
page_size | number | Number of items per page (default: 30, max: 100) |
Cursors are opaque strings — don’t try to parse or construct them. Always use the exact cursor value from the API response.
Paginated Endpoints
Not all endpoints support pagination. Here are the ones that do:
| Endpoint | Returns |
|---|---|
/v1/files/:key/components | Published components |
/v1/files/:key/component_sets | Component sets |
/v1/files/:key/styles | Published styles |
/v1/files/:key/comments | Comments |
/v2/webhooks | Webhook subscriptions |
/v1/files/:key/variables/local | Local variables |
Best Practices
- Set a reasonable
page_size— Use 50-100 for batch operations - Handle rate limits between pages — Add a small delay if processing many pages
- Stream results — Process each page as it arrives rather than collecting everything in memory
- Cache cursors — If your integration supports resumable sync, store the last cursor