screen size not supported

Paginated API response JSON example

Last updated 2026-05-20

When to use this

Use this for any list endpoint that supports paging. The wrapper shape — items, total, skip, limit — is the same one /products, /users, /posts, /todos, and /comments use, so it ports straight into your own API.

Example JSON

Standard offset/limit envelope returned by every list endpoint.
{
  "items": [
    {
      "id": 1,
      "title": "First item"
    },
    {
      "id": 2,
      "title": "Second item"
    },
    {
      "id": 3,
      "title": "Third item"
    }
  ],
  "total": 250,
  "skip": 0,
  "limit": 30
}

Request examples

async function listAll(url) {
  const out = [];
  let skip = 0;
  for (;;) {
    const res = await fetch(url + '?skip=' + skip + '&limit=30');
    const page = await res.json();
    const items = page.items || page.products || page.users || page.posts;
    out.push(...items);
    skip += page.limit;
    if (skip >= page.total) break;
  }
  return out;
}

Try the live endpoint

Click below to call /products?limit=3&skip=0 from your browser.

// click the button to populate this block

Common variations

Cursor-style pagination

An alternative cursor shape if you migrate off offset/limit.

{
  "items": [
    {
      "id": 41
    },
    {
      "id": 42
    },
    {
      "id": 43
    }
  ],
  "pageInfo": {
    "hasNextPage": true,
    "endCursor": "eyJpZCI6IDQzfQ=="
  }
}
Last page (limit reached)
{
  "items": [
    {
      "id": 249
    },
    {
      "id": 250
    }
  ],
  "total": 250,
  "skip": 248,
  "limit": 30
}
Empty page
{
  "items": [],
  "total": 0,
  "skip": 0,
  "limit": 30
}

Convert this JSON

Generated starting points for TypeScript, JSON Schema, and Zod. Refine before shipping to production.

export interface Paginated {
  "items": {
    "id": number;
    "title": string;
  }[];
  "total": number;
  "skip": number;
  "limit": number;
}