Skip to content

Withdraw a request you raised (user)

Withdraw a request you raised yourself. No body.

One route for all three kinds. v1 spells this three different ways - a POST with the id in the path for absences, a POST without it for home office, and a PUT setting status: canceled for corrections - and all three are v1-only, which left the employee half of the feature straddling two API versions while the validator half did not.

Never a hard delete, and the row you get back is not always the one you sent. What withdrawing means depends on how far the request got:

Absence and home office (absences, home-office):

State What happens Response describes
Still pending Cancelled outright, pending approvals dropped the cancelled request
Already approved A removal request is opened for a validator to decide, because the days are booked and giving them back is itself a decision the new removal request
A pending removal Revoked, original restored exactly as a validator rejecting the removal would leave it the restored original

So read the returned request rather than assuming the id you sent is now cancelled. status and progress say which branch happened.

Taking back a removal works from either id - the removal's own, or the original's while it sits at pending_removal. Both answer with the restored original, so a client can use whichever it is holding.

Corrections (time-point-corrections) take a pending correction only, and answer 400 for anything else.

An accepted correction has already changed the timeline, and undoing it means raising a reversal correction that a validator approves - a new request with its own decision behind it, not a withdrawal. v1's PUT .../corrections/{id} raises that reversal implicitly; this endpoint refuses instead of creating something the caller did not ask for.

The asymmetry with absence is deliberate: removal is a modelled part of the absence lifecycle, with its own statuses and validator-queue entries, while a correction reversal is a synthesised row - so it stays an explicit act rather than a side effect of cancelling.

Requester only. A validator's way of stopping a request is to reject it, which is recorded against them; withdrawing leaves no decision behind. A validator gets 403 here even on a request they are asked to decide.

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>
pbx path · string · uuid *
UUID of the PBX tenant. Must be the tenant the token belongs to; anything else is refused with 403 rather than answered from another tenant.
kind path · string *
Which kind of request the id names. The same three values the pending queues use, and the same `kind` each queue entry carries, so a client passes back what it was given. Required rather than inferred: absence and home office requests share one table, so an id alone cannot say which of the two it is. A path whose kind does not match the row returns 404 rather than answering about the other type.
enum: absences home-office time-point-corrections
id path · string · uuid *
UUID of the request, as returned by the queues and the own-requests feed.
accept header · string
example: application/json

Responses

OK. The request the caller should now show - which is the counter-request, not the original, when the withdrawal opened one.
Response schema
kind*string
Which request type this is, and therefore which payload `request` holds.
enum: absences home-office time-point-corrections
example: absences
request*object
The request itself. A transaction for `absences` and `home-office`, a time-point correction for `time-point-corrections`.
progress*object | null
Where a request stands in its approval chain: how far it has got, who moved it, and who it is waiting on. **Null when nobody was ever asked** - a request created already approved by an admin, or raised before approval chains existed and never given v1 rows. That is not the same as a chain waiting on nobody, which is an empty `waiting_on` on a real ladder. Read the request's own status for the outcome in that case, and show "no approval chain applied" rather than a ladder of zeroes. A request decided by the older v1 engine DOES get a block: it has no steps, so the ladder is empty, but `legacy` is true and `approved_by` names who answered. Names are the ones frozen on each approval row when it was written, so a validator who has since been deleted still reads correctly.
current_stepstring | null
The name of the step holding the request, or null when no step is active - either because it is settled or because there is no chain.
example: Team lead
steps_total*integer
How many steps this request's chain holds.
example: 3
steps_done*integer
How many of them are completed. With `steps_total` this is the "2 of 3" a status display shows.
example: 1
legacy*boolean
True for a request raised before approval chains existed. Worth reading: such a request has no steps and would otherwise look unconfigured rather than like an older one finishing where it started.
example:
waiting_on*array<object>
The validators still to answer at the step currently holding the request. Only that step: earlier ones are settled and later ones have not been asked. On a request decided by validator rules (`legacy: true`), every validator who has not answered yet. Empty on a settled request. One entry per person.
employee_id*string | null · uuid
The validator's employee id. Compare it with your own to tell whether the request waits on you.
example: 550e8400-e29b-41d4-a716-446655440031
name*string
Display name, frozen on the approval row when it was written.
example: Muller Jonas
approved_by*array<object>
Everyone who has approved so far, across every step and the supervisors. One entry per person.
employee_id*string | null · uuid
The approver's employee id.
example: 550e8400-e29b-41d4-a716-446655440030
name*string
Display name, frozen on the approval row when it was written.
example: Lemaire Farid
next_stepobject | null
The step that will be asked once the current one completes, or null when this is the last one. Lets a client say what happens next rather than only what is happening.
labelstring
example: HR
orderinteger
example: 2
steps*array<object>
The whole ladder, in the order it is asked.
orderinteger
This step's place in the chain, counting from 1.
example: 1
labelstring
The step's name, or a generated "Step n" when the chain left it unnamed.
example: Team lead
statusstring
`active` holds the request; `pending` has not been reached; `bypassed` was skipped, either because nobody on it covers this request type or because the request was settled above it.
enum: pending active completed bypassed rejected
example: completed
status_labelstring | null
The status as a sentence, already translated.
example: Approved by Lemaire Farid
passed_overboolean
Completed with nobody on this step answering - a supervisor settled the request, or an admin closed the chain. Worth drawing differently from a real approval.
example:
requiredinteger
How many approvals this step needs before it completes.
example: 1
approvedinteger
How many it has.
example: 1
validatorsarray<object>
employee_idstring | null · uuid
The validator's employee id.
example: 550e8400-e29b-41d4-a716-446655440030
namestring
example: Lemaire Farid
statusstring
enum: pending accepted rejected
example: accepted
mandatoryboolean
Their approval is required for the step to complete, whatever its quorum.
example:
supervisors*array<object>
People on the chain outside the ladder: told about the request, and where granted the power, able to settle it at any point. v1 calls these supervisors.
employee_idstring | null · uuid
The supervisor's employee id.
example: 550e8400-e29b-41d4-a716-446655440032
namestring
example: Weber Ines
statusstring
enum: pending accepted rejected
example: pending
can_decideboolean
Whether they may settle the request outright.
example: 1
Bad request. There is nothing to withdraw: the request is already cancelled, rejected, removed or closed - or it is an accepted correction, which needs a reversal correction rather than a withdrawal.
Response schema
No response body.
Authorization Token Missing. This error is returned when the authorization token is missing.
Response schema
errorstring
Error message
example: Authorization Token is missing
Forbidden. Only the employee who raised the request may withdraw it.
Response schema
No response body.
Not found, or its kind does not match the path.
Response schema
No response body.
post https://cockpit.voxbi.com/api/v1/v2/{pbx}/requests/{kind}/{id}/cancel
Base URL
Request sample
curl -X POST 'https://cockpit.voxbi.com/api/v1/v2/{pbx}/requests/{kind}/{id}/cancel' \
  -H 'Authorization: Bearer YOUR_TOKEN'
const response = await fetch('https://cockpit.voxbi.com/api/v1/v2/{pbx}/requests/{kind}/{id}/cancel', {
  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/v2/{pbx}/requests/{kind}/{id}/cancel',
    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/v2/{pbx}/requests/{kind}/{id}/cancel', false, $context);
$data = json_decode($response, true);
print_r($data);
No example for this status.
No example for this status.
{ … }
"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
No example for this status.
No example for this status.