SafetyCulture's Data Feeds API has 39 read-only feeds, and only 13 declare a change filter

SafetyCulture's Data Feeds API has 39 read-only feeds, and only 13 declare a change filter

The SafetyCulture Data Feeds API exports a workplace operations account as flat data: inspections and inspection items, actions, issues, assets, sites, users, schedules, training progress, contractor companies and credentials. All 39 operations are GETs, and only 13 declare a parameter that filters on when a record was modified, created or triggered, so most of these feeds offer no declared way to fetch just what changed.

What ships

SafetyCulture scores 75.5 on the Kin Score, in the exemplar band, and 28.1 on Agent Readiness, in the agent-aware band. This API is one of 27 listed, with 418 operations between them. Its record carries an OpenAPI contract titled Mitti Data Feeds API, documentation, an API reference, a getting-started guide, authentication and rate-limit records, a webhooks AsyncAPI, an llms.txt and six JSON Schemas. Auth is a bearer token. The rate-limit record gives a 60-second window, x-ratelimit-* headers and a 429 when you go over.

The observation: three paging styles and two generations

Taken one at a time, the feeds look uniform. Run a sync over all of them and they do not.

Declared behaviour Feeds Examples
next_page_token 20 /feed/action_fields, /scheduling/v1/feed/schedules
offset only 8 /feed/schedules, /training/v1/feed/training-course-progress
No paging parameter 11 /feed/inspections, /feed/issues, /feed/users
Change filter 13 /feed/inspections, training’s modifiedAfter
Date window only 2 Both schedule_occurrences feeds, start_date and end_date
No time parameter 24 /feed/issues, /feed/assets, /incidents/v1/feed/investigations

The feeds with no paging parameter are not necessarily unpaged. The feed metadata objects return next_page, and two of the three also return next_page_token, so the reliable client follows next_page and never builds the URL itself. That is the good design hiding in here. A generated client working from parameters alone would miss it. The metadata’s description also tells you to send page_token in the request body, on an API that is all GETs. That wording is worth correcting.

Naming varies too: modified_after on most filtered feeds, modifiedAfter on training. The training feed uses camelCase across its multi-word parameters.

The surface also carries two generations of the same data. /feed/schedules has the summary “Data feed for Schedules (legacy)” and sits next to /scheduling/v1/feed/schedules. The same pairing holds for schedule assignees and occurrences, and /feed/action_fields has a twin at /tasks/v1/feed/action_fields, whose operation ID is FeedService_FeedActionFields2. No operation is marked deprecated, so only the summary tells you which to prefer, and only on some of them.

For the 26 feeds without a change filter, plan on a full re-read or on a different signal. SafetyCulture’s webhooks are the obvious candidate, and they are in the record.

Our notes

The provider record says api_count: 1, because the source is one published definition that we split into 27 APIs. The description and the page’s base URL name api.safetyculture.io, while this contract’s server is https://api.mitti.com and its title and contact say Mitti. The record does not explain the difference. If you are integrating, confirm the host in the developer docs. Reconciling those two values on the page is ours to do.

Takeaway

Treat this as a bulk export with a mixed contract: follow next_page, skip the legacy schedule paths, and pair the unfiltered feeds with webhooks. Start at the Data Feeds API page.

← RouterPlex prices five abliterated routes and the catalog confirms the 402 it documents
SiftingIO cuts 600 upstream calls to 2 and the catalog backs the API behind the cache →