Ticket Custom Field Definitions
The five endpoints that define and change the custom fields on the ticket form.
Overview
These five endpoints define the extra form fields a client fills in when opening a support ticket. The type, whether it is required, where it sits and which department it belongs to are structural; the label, description and option names are kept per language.
What lives here are definitions rather than answers. The values a client types sit encrypted on the ticket's own record and show up in the ticket detail, and these endpoints never touch them.
The write contract is unusual: the update wants the whole definition despite its name. Translations and options are written again for every language.
Reference
Listing the Fields
Returns the custom fields on the ticket form, in order.
text, textarea, password, select, radio, checkbox.curl 'https://panel.example.com/api/v1/admin/tickets/custom-fields?status=active' \
-H "Authorization: Bearer $API_KEY"const url = new URL('https://panel.example.com/api/v1/admin/tickets/custom-fields');
url.searchParams.set('status', 'active');
const res = await fetch(url, {
headers: { Authorization: `Bearer ${apiKey}` },
});
const body = await res.json();$ch = curl_init('https://panel.example.com/api/v1/admin/tickets/custom-fields?' . http_build_query(['status' => 'active']));
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $apiKey],
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// The list carries ONE LANGUAGE; read a field on its own to see every translation.
$fields = Api::Tickets()->GetTicketCustomFields([], ['status' => 'active'])['data'];Creating a Field
Adds a field to the ticket form and writes its translations.
text, textarea, password, select, radio, checkbox.curl -X POST 'https://panel.example.com/api/v1/admin/tickets/custom-fields' \
-H "Authorization: Bearer $API_KEY" \
-H 'Content-Type: application/json' \
-d '{"type":"select","required":true,"translations":{"tr":{"name":"Sunucu bolgesi"}},"options":{"tr":["Avrupa","Kuzey Amerika"]}}'const res = await fetch('https://panel.example.com/api/v1/admin/tickets/custom-fields', {
method: 'POST',
headers: {
Authorization: `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
type: 'select',
required: true,
translations: { en: { name: 'Server location', description: '' } },
options: { en: ['Europe', 'North America'] },
}),
});
const body = await res.json();$ch = curl_init('https://panel.example.com/api/v1/admin/tickets/custom-fields');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $apiKey,
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'type' => 'select',
'required' => true,
'translations' => ['en' => ['name' => 'Server location', 'description' => '']],
'options' => ['en' => ['Europe', 'North America']],
]),
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// The ORDER of options is their identity: write the same option at the same place in each language.
Api::Tickets()->CreateTicketCustomField([
'type' => 'select',
'translations' => [
'en' => ['name' => 'Server location'],
'tr' => ['name' => 'Sunucu bolgesi'],
],
'options' => [
'en' => ['Europe', 'North America'],
'tr' => ['Avrupa', 'Kuzey Amerika'],
],
]);Reading One Field
Returns a field with all of its translations.
text, textarea, password, select, radio, checkbox.curl 'https://panel.example.com/api/v1/admin/tickets/custom-fields/4' \
-H "Authorization: Bearer $API_KEY"const res = await fetch(`https://panel.example.com/api/v1/admin/tickets/custom-fields/${fid}`, {
headers: { Authorization: `Bearer ${apiKey}` },
});
const body = await res.json();$ch = curl_init('https://panel.example.com/api/v1/admin/tickets/custom-fields/' . $fid);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $apiKey],
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// Read this BEFORE updating: the write call wants the WHOLE definition.
$field = Api::Tickets()->GetTicketCustomField(['fid' => $fid])['data'];Updating a Field
Writes a field's definition again.
text, textarea, password, select, radio, checkbox.curl -X PATCH 'https://panel.example.com/api/v1/admin/tickets/custom-fields/4' \
-H "Authorization: Bearer $API_KEY" \
-H 'Content-Type: application/json' \
-d '{"type":"select","status":"inactive","translations":{"tr":{"name":"Sunucu bolgesi"}},"options":{"tr":["AB","ABD","Asya"]}}'const res = await fetch(`https://panel.example.com/api/v1/admin/tickets/custom-fields/${fid}`, {
method: 'PATCH',
headers: {
Authorization: `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
type: 'select',
status: 'inactive',
translations: { en: { name: 'Server region', description: '' } },
options: { en: ['EU', 'US', 'Asia'] },
}),
});
const body = await res.json();$ch = curl_init('https://panel.example.com/api/v1/admin/tickets/custom-fields/' . $fid);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'PATCH',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $apiKey,
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'type' => 'select',
'status' => 'inactive',
'translations' => ['en' => ['name' => 'Server region', 'description' => '']],
'options' => ['en' => ['EU', 'US', 'Asia']],
]),
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// Even to flip one switch, send the WHOLE definition; whatever you leave out is dropped.
$cur = Api::Tickets()->GetTicketCustomField(['fid' => $fid])['data'];
$cur['fid'] = $fid;
$cur['status'] = 'inactive';
Api::Tickets()->UpdateTicketCustomField($cur);Deleting a Field
Removes a field and every one of its language records.
curl -X DELETE 'https://panel.example.com/api/v1/admin/tickets/custom-fields/4' \
-H "Authorization: Bearer $API_KEY"const res = await fetch(`https://panel.example.com/api/v1/admin/tickets/custom-fields/${fid}`, {
method: 'DELETE',
headers: { Authorization: `Bearer ${apiKey}` },
});
const body = await res.json();$ch = curl_init('https://panel.example.com/api/v1/admin/tickets/custom-fields/' . $fid);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'DELETE',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $apiKey],
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// To take it off the form, SWITCH IT OFF rather than delete: old answers keep their label.
Api::Tickets()->UpdateTicketCustomField($cur + ['status' => 'inactive']);Pitfalls
Whatever the method name suggests, the body is the whole definition. Translations and options are written again for every language, so a language or an option you leave out is dropped. To change one key, read the detail first, adjust it and send the whole thing back.
An option's identity is where it sits: the first label in each language names the same option. Reordering one language renames a different option in that language, and nothing warns you. A row filled in one language and empty in another is refused outright.
A save wants a label in every live language on the installation. A script that sends only your own language stops working the day a second one is switched on. Read the list from the settings rather than writing it into the code, because it changes.
Zero in the department field means every department, so the field shows on every ticket form. Zero in the rank field does not mean first; it appends to the end. Mixing them up gives you a field everyone sees, sitting at the bottom of the list.
A delete removes only the definition and its translations. Values clients filled in earlier stay on their own ticket records, with no label left to name them. When you want the field off the form, switch it off rather than delete it: past tickets stay readable that way.
Related Articles
Vielen Dank für Ihre Rückmeldung!
Unser Support-Team ist rund um die Uhr für Sie da, wenn Sie oben nicht fündig werden.