JobActivity flag combinations

I’m building reporting against /jobactivity.json and have hit two specifics the API reference doesn’t fully cover. Both relate to the boolean/integer flags on a JobActivity record:

  • activity_was_scheduled (boolean)
  • activity_was_recorded (boolean)
  • activity_was_automated (integer)
  • has_been_opened (boolean)
  • has_been_opened_timestamp (string)

The reference says activity_was_scheduled and activity_was_recorded “cannot be true if [the other] is true” — clear enough. The two questions below are what I’d love clarified:


1. What do the integer values of activity_was_automated represent?

The reference describes the field as:

Integer flag indicating if the activity was automated: 0

That’s the only example given. In real account data I’m seeing activity_was_automated take values 0, 1, 2, 3, and 4. They appear only on rows where activity_was_recorded = 1 (i.e. never on scheduled rows). For example, the distribution on one production account looks roughly like:

activity_was_automated Count Notes
0 majority of recorded rows manual Start/End on the mobile app, presumably
1 small share
2 larger share
3 medium share
4 rare; only this value comes paired with non-zero travel_distance_in_meters

I’d guess the non-zero values correspond to the different signals that ServiceM8’s Automated Time Tracking fires on (auto clock-on/off, auto check-in/out, travel-time inclusion), but the mapping isn’t documented anywhere I can find.

Could someone confirm what each integer value of activity_was_automated represents? Even an informal mapping (e.g. 1 = auto clock-on, 2 = auto check-in via GPS, 4 = travel) would let downstream tools surface meaningful labels instead of “automation type 3”.


2. What does it mean when activity_was_scheduled AND activity_was_recorded are both 0?

The reference describes the two flags as a binary state — scheduled or recorded — with the constraint that they’re mutually exclusive. It doesn’t describe a third state where both are zero, but I see this in real data (~6% of active activity rows on the test account I’m querying).

These rows still have valid start_date, end_date, staff_uuid, job_uuid, and a sensible duration. They’re not edge-case malformed records — they look exactly like normal time blocks on a job, just without either flag set.

A few possibilities I can think of:

  • Records back-entered via the API by an integration that doesn’t set either flag
  • Old records predating the flags
  • Some legitimate “manual office adjustment” path in the SM8 UI that creates rows without setting either flag
  • A bug

Could someone confirm whether this state is valid, and if so, what creates it? It matters because for a “time on site” metric you have to decide whether to count these rows toward actual time worked (which I’m currently doing, treating them like recorded entries) or ignore them.

Hi David,

A couple of clarifications here.

activity_was_automated is only meaningful for recorded JobActivity rows. It is not a staff clock-on/clock-off flag; staff shift events are recorded separately. For JobActivity, the values are best read as the provenance of an automated job check-in/check-out:

activity_was_automated Meaning
0 Not automated / manually recorded
1 Check-in/start was automated
2 Check-out/end was automated
3 Both check-in/start and check-out/end were automated
4 Complete automated job visit recorded by the app as one activity, commonly with travel time/distance populated

For reporting labels, I would treat any non-zero value as “automated”, then use the above labels if you want to be more specific. Be prepared for future values to appear, so an unknown non-zero value should still fall back to “Automated”.

For the second question: activity_was_scheduled = 0 and activity_was_recorded = 0 is a valid stored state, but it is an unclassified JobActivity. Normal ServiceM8 booking/check-in flows should set one of the two flags:

  • scheduled booking: activity_was_scheduled = 1, activity_was_recorded = 0
  • recorded/check-in time: activity_was_scheduled = 0, activity_was_recorded = 1

The common cause of 0/0 rows is data created through the API or legacy/import paths where neither flag was supplied. The API constraint is “not both true”; it does not imply “exactly one must be true”.

For a “time on site” metric, I would not silently mix 0/0 rows into standard recorded time unless you know their source and business meaning. The safest default is:

active = 1
AND activity_was_recorded = 1
AND end_date != '0000-00-00 00:00:00'

If those 0/0 rows are from an integration you control and they genuinely represent worked time, set activity_was_recorded = 1 when creating them, or backfill that flag where appropriate. If you cannot identify the source, keep them in a separate “unclassified activity” bucket rather than treating them as normal recorded check-ins.

Also, has_been_opened and has_been_opened_timestamp are only relevant for scheduled bookings. They can be ignored for recorded or unclassified time rows.

One extra precision on value 4: this is the app’s “Trips” inclusion path during checkout.

When a user includes selected trips while checking out, the app creates separate recorded JobActivity rows for those selected Visit records, sets activity_was_recorded = 1, sets activity_was_scheduled = 0, copies the trip travel time/distance, and marks them with activity_was_automated = 4.

So a more precise label for 4 would be Trip included on checkout or Travel/trip activity, rather than generic auto check-in/check-out. That also explains why you only see this value paired with non-zero travel_distance_in_meters.

Thanks so much mate this is super helpful