Ticket Settings
The six endpoints for the support area's settings, its e-mail setup and its custom statuses.
Overview
These six endpoints decide how the support area behaves. Two hold the general settings, two configure tickets arriving by e-mail, and two manage the statuses an installation defines for itself.
Among the general settings are three blocking switches: for the blacklisted, for those with no service, and for unverified accounts. Each stops a client opening a ticket, so this is the first place to look when the support queue falls unexpectedly quiet.
Custom statuses sit on top of the standard ones. A status such as "Awaiting parts" shows with its own colour and name, while for the workflow it behaves as whichever standard status it was built on.
Reference
Reading the Support Settings
Returns the general settings of the support area.
curl 'https://panel.example.com/api/v1/admin/tickets/settings' \
-H "Authorization: Bearer $API_KEY"const res = await fetch('https://panel.example.com/api/v1/admin/tickets/settings', {
headers: { Authorization: `Bearer ${apiKey}` },
});
const body = await res.json();$ch = curl_init('https://panel.example.com/api/v1/admin/tickets/settings');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $apiKey],
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// Three blocking settings stop a CLIENT opening one; check these first when support goes quiet.
$s = Api::Tickets()->GetTicketSettings()['data'];Writing the Support Settings
Changes the general support settings.
curl -X PUT 'https://panel.example.com/api/v1/admin/tickets/settings' \
-H "Authorization: Bearer $API_KEY" \
-H 'Content-Type: application/json' \
-d '{"listing_count":25,"refresh_time":60,"ticket_claiming":true}'const res = await fetch('https://panel.example.com/api/v1/admin/tickets/settings', {
method: 'PUT',
headers: {
Authorization: `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
listing_count: 25,
refresh_time: 60,
ticket_claiming: true,
}),
});
const body = await res.json();$ch = curl_init('https://panel.example.com/api/v1/admin/tickets/settings');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'PUT',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $apiKey,
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'listing_count' => 25,
'refresh_time' => 60,
'ticket_claiming' => true,
]),
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// An out-of-range value is NOT refused but pulled to the limit; read back what returned.
$now = Api::Tickets()->UpdateTicketSettings(['refresh_time' => 1])['data'];
// $now['refresh_time'] === 5Reading the Mail Settings
Returns how tickets arriving by e-mail are set up.
curl 'https://panel.example.com/api/v1/admin/tickets/pipe-settings' \
-H "Authorization: Bearer $API_KEY"const res = await fetch('https://panel.example.com/api/v1/admin/tickets/pipe-settings', {
headers: { Authorization: `Bearer ${apiKey}` },
});
const body = await res.json();$ch = curl_init('https://panel.example.com/api/v1/admin/tickets/pipe-settings');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $apiKey],
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// This is configuration ONLY; authorising a mailbox does not happen through this endpoint.
$pipe = Api::Tickets()->GetTicketPipeSettings()['data'];Writing the Mail Settings
Changes how tickets arriving by e-mail are set up.
curl -X PUT 'https://panel.example.com/api/v1/admin/tickets/pipe-settings' \
-H "Authorization: Bearer $API_KEY" \
-H 'Content-Type: application/json' \
-d '{"enabled":true,"method":1,"spam_control":true,"prefix":"REF"}'const res = await fetch('https://panel.example.com/api/v1/admin/tickets/pipe-settings', {
method: 'PUT',
headers: {
Authorization: `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
enabled: true,
method: 1,
spam_control: true,
prefix: 'REF',
}),
});
const body = await res.json();$ch = curl_init('https://panel.example.com/api/v1/admin/tickets/pipe-settings');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'PUT',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $apiKey,
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'enabled' => true,
'method' => 1,
'spam_control' => true,
'prefix' => 'REF',
]),
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// CHANGING the prefix leaves replies carrying the old subject unable to find their ticket.
Api::Tickets()->UpdateTicketPipeSettings(['prefix' => 'REF']);Listing the Custom Statuses
Returns the ticket statuses the installation defined for itself.
open, waiting, process, replied, solved.curl 'https://panel.example.com/api/v1/admin/tickets/custom-statuses' \
-H "Authorization: Bearer $API_KEY"const res = await fetch('https://panel.example.com/api/v1/admin/tickets/custom-statuses', {
headers: { Authorization: `Bearer ${apiKey}` },
});
const body = await res.json();$ch = curl_init('https://panel.example.com/api/v1/admin/tickets/custom-statuses');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $apiKey],
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// A custom status sits ON TOP of a standard one: the workflow follows the base.
$custom = Api::Tickets()->GetTicketCustomStatuses()['data'];Writing the Custom Statuses
Replaces every custom status with the list you send.
open, waiting, process, replied, solved. An unknown value falls back to the in-process one.curl -X PUT 'https://panel.example.com/api/v1/admin/tickets/custom-statuses' \
-H "Authorization: Bearer $API_KEY" \
-H 'Content-Type: application/json' \
-d '{"statuses":[{"type":"process","color":"#3399ff","langs":{"tr":"Parca bekleniyor"}}]}'const res = await fetch('https://panel.example.com/api/v1/admin/tickets/custom-statuses', {
method: 'PUT',
headers: {
Authorization: `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
statuses: [
{
type: 'process',
color: '#3399ff',
langs: { en: 'Awaiting parts', tr: 'Parca bekleniyor' },
},
],
}),
});
const body = await res.json();$ch = curl_init('https://panel.example.com/api/v1/admin/tickets/custom-statuses');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'PUT',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $apiKey,
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'statuses' => [[
'type' => 'process',
'color' => '#3399ff',
'langs' => ['en' => 'Awaiting parts'],
]],
]),
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// Even to add one, read the CURRENT list and append; the write is a full replacement.
$all = Api::Tickets()->GetTicketCustomStatuses()['data'];
$all[] = ['type' => 'waiting', 'color' => '#999999', 'langs' => ['en' => 'On hold']];
Api::Tickets()->UpdateTicketCustomStatuses(['statuses' => $all]);Pitfalls
The write endpoint replaces the whole set with what you send: the existing statuses go and yours are added in their place. Sending only the one you meant to add removes the rest. Read the current list first, append to it and send the whole thing back.
Because a full replacement removes the old rows and inserts new ones, custom statuses get new ids. If you keep the id assigned to a ticket on your side, that number may now point at a different status. Resolve from the list each time rather than storing ids.
With the blacklist, no-service and verification switches on, a client cannot open a ticket at all. Nothing shows as an error in the panel, the queue stays empty, and that is easy to read as a fault. When no tickets arrive on an installation, read these three fields first.
Which ticket an incoming e-mail belongs to is read from the reference prefix in the subject line. Change the prefix and replies still carrying the old subject cannot find their ticket, landing as new ones instead. Leave the prefix alone while conversations are in flight.
The page size and the refresh interval are pulled into set ranges. Asking for a one-second refresh raises no error; the setting quietly lands on the lowest value allowed. Do not assume what you sent was written, and read the value that comes back.
Related Articles
Thanks for your feedback!
Our support team is here around the clock for anything you can't find above.