Credit travel time to a day
Credits the employee's configured travel time allowance to a date.
Two successful outcomes, both on the happy path:
201— the minutes were placed and paid; the body carries the time point.202— the day had no room the system would use, so the request was filed as a PENDING time point correction for a validator to place by hand. Nothing has been credited yet and the allowance is untouched.
Placement. A day's payable total is bounded by the shape of its rows: each row runs until the next one starts, so a block laid over payable time only relabels minutes already counted. Only a placement that replaces UNPAYABLE time, or extends past the day's outer edge, actually pays. Three are tried in order, and the first that fits the WHOLE allowance wins:
start_of_day— ends exactly where the day's first PAYABLE status begins. Unpayable rows at the start of a day (a midnight rollover row, an auto-stop row, an early break) are room rather than an obstacle.end_of_day— appended after the day's last CLOSED row, then closed again by the employee's own last unpayable status, or the configured stop status.mid_day— the tail of an unpayable stretch, preferring one that work resumes after. This is what covers a day the employee is still clocked in on.
An empty day is anchored at the PBX's configured empty day time (06:00 by default) and closed by the configured stop status. Repeat requests on the same day chain backwards from the earlier credit, producing one contiguous block.
Guarantees. A credit is exactly the configured minutes or it is not written
(partial credits no longer exist); it never crosses another row's boundary, so
at most one existing row is touched — its end pulled back to the credit's start,
with the old value kept in that row's meta_data.travel_time_trimmed; live
(open) rows are never touched; nothing is written into the future. After the
write the day's payable seconds are re-measured and compared against the value
before it — anything other than exactly the allowance is rolled back and
returned as 202.
The credit is recorded as an accepted time point correction, so it appears in the employee's correction history and remains correctable afterwards. No acceptance email is sent.
The caller may only credit their own travel time: the request is rejected with 403 when the authenticated user has no access to the tenant or the employee record is not their own, and with 404 when the employee cannot be found.
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>
application/jsonRequest body
2026-05-11Client site visitResponses
Travel time has been added.data*object
550e8400-e29b-41d4-a716-446655440012550e8400-e29b-41d4-a716-446655440013start_of_day end_of_day mid_day empty_daystart_of_day550e8400-e29b-41d4-a716-4466554400112026-05-11 07:30:002026-05-11 08:00:0030Client site visitmeta*object
100Please contact HR as your day has no room available for adjusting this timepoint. Your request has been sent to them for approval.pending_hr_reviewpending_hr_reviewdata*object
550e8400-e29b-41d4-a716-446655440013550e8400-e29b-41d4-a716-4466554400112026-05-11 06:00:00Client site visitmeta*object
011Authorization Token is missingmessagearray<string>
The travel time limit for this date has already been reached.limit_reachedThe given data was invalid.errors*object
https://cockpit.voxbi.com/api/v1/{pbx_id}/user/{employee_id}/travel-time
curl -X POST 'https://cockpit.voxbi.com/api/v1/{pbx_id}/user/{employee_id}/travel-time' \
-H 'Authorization: Bearer YOUR_TOKEN'
const response = await fetch('https://cockpit.voxbi.com/api/v1/{pbx_id}/user/{employee_id}/travel-time', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${YOUR_TOKEN}`,
},
});
const data = await response.json();
console.log(data);
import requests
response = requests.post('https://cockpit.voxbi.com/api/v1/{pbx_id}/user/{employee_id}/travel-time',
headers={'Authorization': f'Bearer {YOUR_TOKEN}'}
)
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",
],
]);
$response = file_get_contents('https://cockpit.voxbi.com/api/v1/{pbx_id}/user/{employee_id}/travel-time', false, $context);
$data = json_decode($response, true);
print_r($data);
{ … }
private, must-revalidatekeep-aliveapplication/jsonOrigin6057{ … }
"message": [ … ]
private, must-revalidatekeep-aliveapplication/jsonOrigin6057