Skip to content

Pagination and syncing

GET /v1/tasks returns results one page at a time, newest started_at first.

  • limit sets the page size: default 100, maximum 500.
  • Every response carries next_cursor. Pass it back as cursor, with the same filters, to get the next page.
  • When next_cursor is null, 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;
}

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.

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:

  1. Run on a schedule, for example every 15 minutes.
  2. Each run, fetch a trailing window that overlaps the previous one, for example the last 48 hours (from = now - 48h, to = now).
  3. Upsert by id. Tasks you already stored are simply overwritten; new ones are added.
  4. 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.