Skip to content

Pagination and polling

Paginated list endpoints take page and limit query parameters and return the records in data, with paging details in meta.pagination:

{
"data": [{ "id": "…" }],
"meta": {
"pagination": {
"page": 1,
"limit": 50,
"total": 132,
"totalPages": 3,
"hasNext": true,
"hasPrev": false
}
}
}
  • page starts at 1.
  • limit is the number of records per page. The default and maximum depend on the endpoint (see the table below).
  • Keep requesting the next page while hasNext is true.
Endpoint Default limit Maximum limit Sorting updatedAfter / updatedBefore
GET /events 50 Use 100 or less sort, dir Yes
GET /action-items 20 100 — Yes
GET /metrics 100 1000 Always by updatedAt Yes
GET /events/metrics/bulk 100 1000 Always by updatedAt Yes
GET /workflows 50 1000 — —
GET /workflows/{workflowId}/runs 50 1000 — —

GET /assets, GET /locations, GET /users and GET /equipment-types are not paginated: they return every matching record in data in one response.

GET /events takes sort (a field name such as eventDate, createdAt or updatedAt) and dir (asc or desc). By default events are sorted by eventDate, newest first.

To keep another system in sync, don’t re-download everything. Ask for records that changed since your last sync with updatedAfter, and save the newest updatedAt you received as the starting point for the next sync.

This works on GET /events, GET /action-items, GET /metrics and GET /events/metrics/bulk.

  1. On the first run, choose a starting time, for example the start of today, in ISO 8601 UTC: 2026-09-01T00:00:00Z.
  2. Request ?updatedAfter=<cursor>&page=1. When updatedAfter is set, results come back sorted by updatedAt, oldest first. On GET /events, send sort=updatedAt&dir=asc as well, so the order stays right if you add other options.
  3. Page through with page=2, 3, … until hasNext is false, and process each record.
  4. Save the largest updatedAt you saw as the new cursor.
  5. Wait, then repeat from step 2 with the new cursor.
Terminal window
curl "https://safe-api.safetyradar.com/v2/events?updatedAfter=2026-09-01T00:00:00Z&sort=updatedAt&dir=asc&limit=100&page=1" \
--header "Authorization: Bearer $SAFETY_RADAR_API_KEY"
  • Insert or update by id. The same record can appear in two syncs in a row, for example the last record of one sync and the first of the next. Make your processing safe to repeat.
  • Compare timestamps as UTC ISO strings as returned by the API. Strings in this format sort in time order.
  • Metrics use UTC only. On GET /metrics and GET /events/metrics/bulk, send updatedAfter and updatedBefore in UTC with a Z suffix (for example 2026-09-01T00:00:00Z), not with an offset such as +02:00. Their bounds are inclusive, so the record at your cursor is returned again.
  • Poll at a sensible interval. Every few minutes is plenty for most integrations and stays well within the rate limit.