Change User Status
Changes the authenticated user's status in the Tempus time-attendance system. Accepts either a Cockpit UUID or a Tempus mapping ID for the status.
HTTP:
bearerAuth
User bearer token. Default authentication for customer-facing endpoints.
Obtain a token by calling POST /login with your credentials, then send it
on every subsequent request as Authorization: Bearer <token>. The token
inherits the permissions and PBX scope of the authenticated user.
- HTTP Authorization Scheme
bearer- Bearer format
Bearer <token>
Accept
header · string
Request body
Request schema
status_id*string
The status UUID (Cockpit) or mapping ID (Tempus). If not a UUID, the system will attempt to resolve it via the Tempus mapping.
location_idstring | null · uuid
Optional location to associate with the status. Must reference a
location of the caller's own PBX that is enabled for presence
status.
sub_status_idsarray<string>
Sub-status identifiers linked to the selected status. A single
value unless the status allows multiselect; required when the
status mandates a sub-status selection.
[]string · uuid
sourcesarray<string>
Origin channels for the status change.
[]string
triggersarray<string>
Triggers that initiated the status change.
[]string
meta_dataobject | null
Arbitrary metadata, stored verbatim on the time point. GPS
coordinates may be sent here (as `lat`/`lng`,
`latitude`/`longitude`, or `gpsLat`/`gpsLong`) or in `gpsData`.
Either way they are normalised onto the time point as
`device_gps` and compared with `location_id`, with the result
exposed as `location_check`.
Coordinates are recorded as sent and are never replaced by the
coordinates configured on `location_id`.
gpsDataobject | null
The device's GPS fix, as clients have historically sent it. An
alternative container to `meta_data`: both are accepted, both
are stored, and sending both no longer discards this one.
Read tolerantly. An unusable fix (half a pair, non-numeric, or
out of range) does not fail the request: it is stored as sent
and `location_check.reason` reports `no_device_gps`.
commentstring | null
Optional free-text comment.
length: 0–255
Responses
Response schema
uiobject
dataobject
workTimesobject | null
Always null on v2; poll the work-times endpoint instead.
messagestring
A new time point was opened. `ui.data` is the created time point,
including `device_gps` (the coordinates the client sent, stored as sent)
and `location_check` (how they compare with the selected location's
configured coordinates and geofence radius).
Response schema
uiobject
dataobject
A Tempus time point as serialized by the V1 `TimePointResource`. A time point
records a single interval during which an employee was in a given presence or
attendance status (for example working, on break, or off). Each time point
belongs to exactly one Pbx (tenant) and one user, references the status that
was active during the interval, and is bounded by a `start_time` and an
optional `end_time`.
An open time point (one with `end_time` set to null) represents the employee's
current, ongoing status. When a new time point is opened for an employee, any
previously open time point for that same employee is automatically closed by
setting its `end_time`.
This object documents the exact keys returned by the resource, not every raw
database column. Columns such as `successive_count`, `comment`, `mapping_id`,
`deleted_at`, `created_by`, and `updated_by` exist on the model but are not
exposed by this resource. The `sources`, `triggers`, and `meta_data` fields
are stored as JSON and returned as free-form objects.
Location data comes in three distinct parts that must not be conflated:
`location_id` plus the nested `location` object describe the *configured*
location record the employee selected; `device_gps` records where the
*device* said it was; `location_check` is the comparison of the two.
id*string · uuid
Unique time point identifier.
read-only
example:
550e8400-e29b-41d4-a716-446655440000pbx_id*string · uuid
Identifier of the Pbx (tenant) that owns this time point.
example:
550e8400-e29b-41d4-a716-446655440001user_id*string · uuid
Identifier of the user (employee) this time point belongs to.
example:
550e8400-e29b-41d4-a716-446655440002status_id*string · uuid
Identifier of the Tempus status that was active during this interval (for
example working, break, or off). References a `TempusStatus` record.
example:
550e8400-e29b-41d4-a716-446655440003location_idstring | null · uuid
Identifier of the location the status was recorded against. Null when no
location was selected.
example:
550e8400-e29b-41d4-a716-446655440010locationobject | null
The configured location record referenced by `location_id`, including its
own coordinates and geofence radius. Null when `location_id` is null.
These are the location's *configured* coordinates, not the device's: see
`device_gps` for the latter.
idstring · uuid
example:
550e8400-e29b-41d4-a716-446655440010namestring
example:
HQ Luxembourgdescriptionstring | null
street_nostring | null
example:
12streetstring | null
example:
Rue de Bonnevoiecitystring | null
example:
Luxembourgpostalstring | null
example:
1260country_idstring | null · uuid
example:
550e8400-e29b-41d4-a716-446655440011latitudenumber | null · double
The location's configured latitude, in degrees.
example:
49.6008longitudenumber | null · double
The location's configured longitude, in degrees.
example:
6.133geofence_radius_minteger | null
Geofence radius around the configured point, in metres.
example:
150is_fixed_locationboolean
example:
1start_time*string · date-time
Timestamp marking the beginning of the status interval.
example:
2024-03-01T08:29:07Zend_timestring | null · date-time
Timestamp marking the end of the status interval. Null while the time
point is still open, which indicates the employee's current ongoing
status.
example:
2024-03-01T12:00:00Zsourcesobject | null
Free-form JSON object describing the origin systems that contributed to
this time point (for example the cockpit UI, a badge reader, or an API
client). Structure varies by integration. Null when no source data is
recorded.
example:
{"channel":"cockpit","device_id":"550e8400-e29b-41d4-a716-446655440010"}triggersobject | null
Free-form JSON object describing the events that triggered the creation or
closing of this time point (for example a manual status change or an
automated rollover). Structure varies by integration. Null when no trigger
data is recorded.
example:
{"type":"manual_change","actor_id":"550e8400-e29b-41d4-a716-446655440002"}meta_dataobject | null
Free-form JSON object holding additional key-value metadata attached to
the time point, exactly as the client sent it. Keys are
integration-specific. Null when no metadata is stored.
Two keys are written by the server rather than the client: `device_gps`
and `location_check`, both also surfaced as top-level fields of this
resource (see below).
example:
{"note":"Started shift remotely","gpsLat":49.95,"gpsLong":6.133}device_gpsobject | null
The coordinates the client reported when this status was recorded, stored
exactly as sent. Read from whichever field the client already uses
(`gpsData`, or GPS keys inside `meta_data`, under any of the historical
spellings such as `gpsLat` / `lat` / `latitude`).
This is never derived from, corrected by, or overwritten with the
coordinates configured on the selected location: it records where the
device claimed to be, which is only useful as evidence if it is left
untouched. Compare it with `location.latitude` / `location.longitude`,
which describe the configured location record instead.
Null when the request carried no usable fix (no coordinates at all, only
one of the pair, or values outside the valid latitude / longitude range).
A request with an unusable fix still succeeds, and whatever it sent is
preserved verbatim under `meta_data`.
latitude*number · double
Latitude reported by the device, in degrees.
example:
49.95longitude*number · double
Longitude reported by the device, in degrees.
example:
6.133accuracy_mnumber | null · double
Accuracy radius of the fix in metres, as reported by the device. Null
when the client sent none. Used as tolerance by `location_check`.
example:
12.5captured_atstring | null · date-time
The device's GPS timestamp, parsed. Null when the client sent none or
sent a value that could not be parsed.
example:
2026-07-07T10:07:39+00:00captured_at_rawstring | number | null
The GPS timestamp exactly as the client sent it: epoch milliseconds,
epoch seconds, or an ISO 8601 string. Kept alongside the parsed value
so nothing the client reported is lost.
example:
1783418859289location_checkobject | null
Comparison of `device_gps` against the selected location's configured
coordinates and geofence radius. This is the integrity signal: it shows
when an employee recorded a status against a location they were not
actually at.
Null when the time point has neither a device fix nor a location, and on
time points written before this check existed.
location_idstring | null · uuid
The location the status was recorded against, if any.
example:
550e8400-e29b-41d4-a716-446655440010location_latitudenumber | null · double
The location's configured latitude at the time of the check.
example:
49.6008location_longitudenumber | null · double
The location's configured longitude at the time of the check.
example:
6.133geofence_radius_minteger | null
The location's configured geofence radius in metres.
example:
150distance_minteger | null
Distance in metres between the device fix and the location's
configured point. Recorded whenever both sides have coordinates, even
when the location has no geofence radius and no in-or-out verdict is
possible: the distance alone is the useful signal.
example:
38957within_geofenceboolean | null
Whether the device fix falls inside the geofence. The device's own
reported accuracy is added to the radius as tolerance, so a poor fix
slightly outside a small geofence is not treated as a discrepancy.
Null when no verdict was possible.
example:
verdictstring
`match`: the device fix is inside the geofence.
`mismatch`: the device fix is outside it, meaning the selected
location disagrees with where the device said it was.
`unknown`: not enough data to judge, see `reason`.
enum:
match mismatch unknownexample:
mismatchreasonstring | null
Why the verdict is `unknown`. `no_device_gps`: the request carried no
usable fix. `no_location`: no location was selected, or it does not
belong to this tenant. `location_without_coordinates`: the location
record has no coordinates configured. `no_geofence_radius`: the
location has coordinates but no radius, so only `distance_m` is
meaningful. Null when the verdict is `match` or `mismatch`.
enum:
no_device_gps no_location location_without_coordinates no_geofence_radius nullis_synced*boolean
Whether this time point has been synchronized to the downstream
time-and-attendance system. False until the record has been exported.
example:
created_atstring | null · date-time
Timestamp when the time point was created.
read-only
example:
2024-03-01T08:29:07Zupdated_atstring | null · date-time
Timestamp when the time point was last updated.
read-only
example:
2024-03-01T08:29:07ZworkTimesnull
Authorization Token Missing. This error is returned when the authorization token is missing.
Response schema
errorstring
Error message
example:
Authorization Token is missingData Not Found. This error is returned when the requested data is not found.
Response schema
messagearray<string>
[]string
Another status change for this employee is already in progress and could
not be resolved. Retry once after a short delay.
Response schema
datanull
errorsarray<string>
[]string
messagestring
Unprocessable Parameters. This error is returned when a parameter is not valid.
Response schema
messagestring
example:
The given data was invalid.errorsobject
filterarray<string>
[]string
sortarray<string>
[]string
pagearray<string>
[]string
per_pagearray<string>
[]string
Server error. An unexpected condition was encountered on the server and the
request could not be completed. The body is a generic JSON envelope with a
`message` field. The response is logged on the server side; quote the
request URL + timestamp when reporting an issue.
Response schema
messagestring
exceptionstring
Only present in non-production environments.
filestring
Only present in non-production environments.
lineinteger
Only present in non-production environments.
post
https://cockpit.voxbi.com/api/v1/v2/change-status
Base URL
Request sample
curl -X POST 'https://cockpit.voxbi.com/api/v1/v2/change-status' \
-H 'Authorization: Bearer YOUR_TOKEN' \
-H 'Content-Type: application/json' \
--data '{"status_id":"550e8400-e29b-41d4-a716-446655440001","location_id":"550e8400-e29b-41d4-a716-446655440010","sub_status_ids":["550e8400-e29b-41d4-a716-446655440020"],"sources":["mobile"],"triggers":["manual"],"meta_data":{"app_version":"3.4.1"},"gpsData":{"gpsLat":49.95,"gpsLong":6.133,"accuracy":12.5,"gpsTimestamp":1783418859289},"comment":"Starting morning shift"}'
const response = await fetch('https://cockpit.voxbi.com/api/v1/v2/change-status', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${YOUR_TOKEN}`,
},
body: JSON.stringify({
"status_id": "550e8400-e29b-41d4-a716-446655440001",
"location_id": "550e8400-e29b-41d4-a716-446655440010",
"sub_status_ids": [
"550e8400-e29b-41d4-a716-446655440020"
],
"sources": [
"mobile"
],
"triggers": [
"manual"
],
"meta_data": {
"app_version": "3.4.1"
},
"gpsData": {
"gpsLat": 49.95,
"gpsLong": 6.133,
"accuracy": 12.5,
"gpsTimestamp": 1783418859289
},
"comment": "Starting morning shift"
}),
});
const data = await response.json();
console.log(data);
import requests
response = requests.post('https://cockpit.voxbi.com/api/v1/v2/change-status',
headers={'Authorization': f'Bearer {YOUR_TOKEN}'},
json={
"status_id": "550e8400-e29b-41d4-a716-446655440001",
"location_id": "550e8400-e29b-41d4-a716-446655440010",
"sub_status_ids": [
"550e8400-e29b-41d4-a716-446655440020"
],
"sources": [
"mobile"
],
"triggers": [
"manual"
],
"meta_data": {
"app_version": "3.4.1"
},
"gpsData": {
"gpsLat": 49.95,
"gpsLong": 6.133,
"accuracy": 12.5,
"gpsTimestamp": 1783418859289
},
"comment": "Starting morning shift"
}
)
response.raise_for_status()
data = response.json()
print(data)
<?php
$context = stream_context_create([
'http' => [
'method' => 'POST',
'header' => "Content-Type: application/json\r\nAuthorization: Bearer YOUR_TOKEN",
'content' => '{
\"status_id\": \"550e8400-e29b-41d4-a716-446655440001\",
\"location_id\": \"550e8400-e29b-41d4-a716-446655440010\",
\"sub_status_ids\": [
\"550e8400-e29b-41d4-a716-446655440020\"
],
\"sources\": [
\"mobile\"
],
\"triggers\": [
\"manual\"
],
\"meta_data\": {
\"app_version\": \"3.4.1\"
},
\"gpsData\": {
\"gpsLat\": 49.95,
\"gpsLong\": 6.133,
\"accuracy\": 12.5,
\"gpsTimestamp\": 1783418859289
},
\"comment\": \"Starting morning shift\"
}',
],
]);
$response = file_get_contents('https://cockpit.voxbi.com/api/v1/v2/change-status', false, $context);
$data = json_decode($response, true);
print_r($data);
Sample request
{ … }
"status_id": "550e8400-e29b-41d4-a716-446655440001",
"location_id": "550e8400-e29b-41d4-a716-446655440010",
"sub_status_ids": [ … ],
"550e8400-e29b-41d4-a716-446655440020"
],
"sources": [ … ],
"mobile"
],
"triggers": [ … ],
"manual"
],
"meta_data": { … },
"app_version": "3.4.1"
},
"gpsData": { … },
"gpsLat": 49.95,
"gpsLong": 6.133,
"accuracy": 12.5,
"gpsTimestamp": 1783418859289
},
"comment": "Starting morning shift"
}
{ … }
"ui": { … },
"data": []
},
"workTimes": null,
"message": "Status changed successfully."
}
Host
string
example:
0.0.0.0:8083
Date
string
example:
Thu, 12 Oct 2023 12:25:52 GMT
Connection
string
example:
close
Cache-Control
string
example:
no-cache, private
Content-Type
string
example:
application/json
X-RateLimit-Limit
integer
example:
60
X-RateLimit-Remaining
integer
example:
59
Access-Control-Allow-Origin
string
example:
*{ … }
"ui": { … },
"data": { … }
"id": "550e8400-e29b-41d4-a716-446655440000",
"status_id": "550e8400-e29b-41d4-a716-446655440003",
"location_id": "550e8400-e29b-41d4-a716-446655440010",
"start_time": "2026-07-07T10:07:39.000000Z",
"end_time": null,
"device_gps": { … },
"latitude": 49.95,
"longitude": 6.133,
"accuracy_m": 12.5,
"captured_at": "2026-07-07T10:07:39+00:00",
"captured_at_raw": 1783418859289
},
"location_check": { … }
"location_id": "550e8400-e29b-41d4-a716-446655440010",
"location_latitude": 49.6008,
"location_longitude": 6.133,
"geofence_radius_m": 150,
"distance_m": 38957,
"within_geofence": false,
"verdict": "mismatch",
"reason": null
}
}
},
"workTimes": null
}
{ … }
"error": "Authorization Token is missing"
}
Cache-Control
string
example:
private, must-revalidate
Connection
string
example:
keep-alive
Content-Type
string
example:
application/json
Vary
string
example:
Origin
X-RateLimit-Limit
integer
Max requests allowed in the current rate-limit window.
example:
60
X-RateLimit-Remaining
integer
Requests remaining in the current rate-limit window.
example:
57{ … }
"message": [ … ]
"Data not found"
]
}
Cache-Control
string
example:
private, must-revalidate
Connection
string
example:
keep-alive
Content-Type
string
example:
application/json
Vary
string
example:
Origin
X-RateLimit-Limit
integer
Max requests allowed in the current rate-limit window.
example:
60
X-RateLimit-Remaining
integer
Requests remaining in the current rate-limit window.
example:
57{ … }
"data": null,
"errors": [ … ],
"Another status change is already in progress. Please try again."
],
"message": "Status change failed."
}
{ … }
"errors": { … }
"filter": [ … ],
"The filter field must be an array."
],
"sort": [ … ],
"The sort field must be a string."
],
"page": [ … ],
"The page field must be an integer."
],
"per_page": [ … ]
"The per page field must be an integer."
]
}
}
Cache-Control
string
example:
private, must-revalidate
Connection
string
example:
keep-alive
Content-Type
string
example:
application/json
Vary
string
example:
Origin
X-RateLimit-Limit
integer
Max requests allowed in the current rate-limit window.
example:
60
X-RateLimit-Remaining
integer
Requests remaining in the current rate-limit window.
example:
57{ … }
"message": "Server Error"
}