Pagination
List endpoints (/photos, /tags) use opaque cursor pagination. Pass a cursor query parameter to fetch the next page; the response tells you whether more pages exist.
Request
Section titled “Request”GET /api/v1/photos?limit=50&cursor=eyJpZCI6MTIzNH0Authorization: Bearer pp_live_xxxxxxxxxxxxxxxx| Param | Default | Meaning |
|---|---|---|
limit | 50 (max 100) | Items per page. |
cursor | — | Opaque token from the previous response’s nextCursor. Omit on the first request. |
Response
Section titled “Response”{ "data": [ { "id": 1234, "filename": "DSC_0001.jpg", ... }, { "id": 1235, "filename": "DSC_0002.jpg", ... } ], "pagination": { "nextCursor": "eyJpZCI6MTI4NX0", "hasMore": true }}When hasMore is false, you’ve reached the end and nextCursor will be null.
Walking the full list
Section titled “Walking the full list”async function fetchAllPhotos(apiKey) { const all = []; let cursor = undefined; do { const url = new URL('https://api.photopick.cz/api/v1/photos'); url.searchParams.set('limit', '100'); if (cursor) url.searchParams.set('cursor', cursor); const res = await fetch(url, { headers: { Authorization: `Bearer ${apiKey}` }, }); if (!res.ok) throw new Error(`HTTP ${res.status}`); const body = await res.json(); all.push(...body.data); cursor = body.pagination.hasMore ? body.pagination.nextCursor : undefined; } while (cursor); return all;}import httpx
def fetch_all_photos(api_key): out, cursor = [], None while True: params = {'limit': 100} if cursor: params['cursor'] = cursor res = httpx.get( 'https://api.photopick.cz/api/v1/photos', params=params, headers={'Authorization': f'Bearer {api_key}'}, ) res.raise_for_status() body = res.json() out.extend(body['data']) if not body['pagination']['hasMore']: return out cursor = body['pagination']['nextCursor']Consistency guarantees
Section titled “Consistency guarantees”- Cursors are stable for at least 24 hours. A cursor older than that may return
400 invalid_cursorif the underlying ordering shifts. - Items added after you start paginating may or may not appear, depending on insertion order. For a fully-consistent snapshot, complete the pagination loop within a single session.
- Items deleted mid-pagination simply don’t appear on later pages.
For large recurring exports, prefer paginating during off-peak windows and persisting the result, rather than re-paginating on every read.