Pagination and syncing
GET /v1/tasks returns results one page at a time, newest started_at first.
How cursors work
Section titled “How cursors work”limitsets the page size: default100, maximum500.- Every response carries
next_cursor. Pass it back ascursor, with the same filters, to get the next page. - When
next_cursorisnull, you have the last page. - Cursors are opaque. Do not build or modify them. They expire after 24 hours.
async function fetchAllTasks({ from, to, locationIds = [] }) { const tasks = []; let cursor = null; do { const params = new URLSearchParams({ from, to, limit: "500" }); locationIds.forEach((id) => params.append("location_id", id)); if (cursor) params.set("cursor", cursor);
const response = await fetch(`https://api.uniqueonthego.com/v1/tasks?${params}`, { headers: { Authorization: `Bearer ${await getToken()}` }, }); if (!response.ok) throw new Error(`Request failed: ${response.status}`);
const page = await response.json(); tasks.push(...page.data); cursor = page.next_cursor; } while (cursor); return tasks;}Time windows
Section titled “Time windows”from is inclusive and to is exclusive, both on started_at. The window can
span at most 31 days. To backfill a longer period, walk it one window at a
time, for example month by month.
Keeping your data in sync
Section titled “Keeping your data in sync”Tasks are recorded on site and can reach our system a few hours after the work started, for example when a device regains connectivity. A reliable sync loop:
- Run on a schedule, for example every 15 minutes.
- Each run, fetch a trailing window that overlaps the previous one, for
example the last 48 hours (
from = now - 48h,to = now). - Upsert by
id. Tasks you already stored are simply overwritten; new ones are added. - Once a day, re-pull the previous 7 days to catch anything late.
Because every task has a stable id, overlapping windows never produce
duplicates on your side.