The use of the Fields plugin via the High Level API is not yet available. This documentation only concerns the Legacy API.
- Overview
- Prerequisites
- Authentication
- Understanding Field Naming
- Container Types & Targeting
- Creating Items with Custom Fields
- Updating Items with Custom Fields
- Field Types Reference
- Reading Custom Field Values
- Searching Items by Custom Fields
- Multiple Values Fields
- Complete Workflow Examples
- Troubleshooting
The Fields plugin allows custom fields to be created and updated via the GLPI REST API. Custom fields are passed directly alongside native GLPI fields in the input object of create (POST) and update (PUT) requests.
Minimum versions required:
- GLPI ≥ 11.0.2
- Fields plugin ≥ 1.23.3 (with fix pluginsGLPI/fields#1154)
Before making API calls, ensure:
- The Fields plugin is installed and enabled
- The API is enabled in Setup > General > API
- An API client exists (with valid IP range and optionally an App-Token)
- The user/token has a profile with Fields rights (read/write on the relevant containers)
- The containers are active and assigned to the target entity
curl -X GET \
'https://glpi.example.com/apirest.php/initSession' \
-H 'Content-Type: application/json' \
-H 'Authorization: Basic BASE64_LOGIN_PASSWORD' \
-H 'App-Token: YOUR_APP_TOKEN'curl -X GET \
'https://glpi.example.com/apirest.php/initSession' \
-H 'Content-Type: application/json' \
-H 'Authorization: user_token YOUR_USER_TOKEN' \
-H 'App-Token: YOUR_APP_TOKEN'{
"session_token": "abc123def456"
}Use
session_tokenin all subsequent requests via theSession-Tokenheader.
When a field is created in the Fields plugin, its internal name (used as the API key) is derived from the label:
- The label is lowercased
- The singular form is extracted
- Only alphanumeric characters are kept
- Digits are replaced by their English name (
0→zero,1→one, etc.) - The suffix
fieldis appended
Examples:
| Label | Internal Name (API key) |
|---|---|
Serial Number |
serialnumberfield |
Cost |
costfield |
Ref. 2024 |
reftwozerotwofourfield |
The exact key to use depends on the field type — see Field Types Reference.
Tip: You can find the exact field names by querying the search options endpoint (see Searching Items by Custom Fields).
The Fields plugin supports three container types:
| Type | Display | Description |
|---|---|---|
dom |
Injected in main form | Fields appear directly in the item's main form. Only one dom container per itemtype. |
tab |
Separate tab | Fields appear in a dedicated tab. Multiple tab containers are allowed. |
domtab |
Injected in a specific tab | Fields are injected inside an existing tab's form. |
When your itemtype has a single dom container, the plugin automatically detects it. You don't need to specify any container identifier — just pass the field keys directly:
{
"input": {
"name": "My Ticket",
"serialnumberfield": "SN-12345"
}
}When targeting a tab or domtab container, or when multiple containers exist for the same itemtype, you must specify the container ID using the c_id key:
{
"input": {
"c_id": 5,
"serialnumberfield": "SN-12345"
}
}
c_idis theidfrom theglpi_plugin_fields_containerstable. You can find it in the Fields plugin configuration page URL, or by querying thePluginFieldsContaineritemtype via API.
To update fields in multiple containers (e.g., one dom + one tab), you need separate API calls, one per container, each with its own c_id.
curl -X POST \
'https://glpi.example.com/apirest.php/Ticket' \
-H 'Content-Type: application/json' \
-H 'Session-Token: YOUR_SESSION_TOKEN' \
-H 'App-Token: YOUR_APP_TOKEN' \
-d '{
"input": {
"name": "Server disk failure",
"content": "<p>Disk /dev/sda1 is failing on srv-prod-01</p>",
"entities_id": 0,
"type": 1,
"urgency": 4,
"impact": 4,
"serialnumberfield": "SRV-2024-0042",
"costfield": "1500.00"
}
}'curl -X POST \
'https://glpi.example.com/apirest.php/Ticket' \
-H 'Content-Type: application/json' \
-H 'Session-Token: YOUR_SESSION_TOKEN' \
-H 'App-Token: YOUR_APP_TOKEN' \
-d '{
"input": {
"name": "Network outage",
"content": "<p>Network is down in building B</p>",
"entities_id": 0,
"c_id": 7,
"locationdetailfield": "Building B, Floor 3",
"affectedusercountfield": "150"
}
}'curl -X POST \
'https://glpi.example.com/apirest.php/Computer' \
-H 'Content-Type: application/json' \
-H 'Session-Token: YOUR_SESSION_TOKEN' \
-H 'App-Token: YOUR_APP_TOKEN' \
-d '{
"input": {
"name": "SRV-PROD-01",
"entities_id": 0,
"states_id": 1,
"assettagnumberfield": "ASSET-2024-001",
"purchasedatefield": "2024-03-15"
}
}'{
"id": 42,
"message": ""
}curl -X PUT \
'https://glpi.example.com/apirest.php/Ticket/42' \
-H 'Content-Type: application/json' \
-H 'Session-Token: YOUR_SESSION_TOKEN' \
-H 'App-Token: YOUR_APP_TOKEN' \
-d '{
"input": {
"id": 42,
"name": "Server disk failure [UPDATED]",
"urgency": 5,
"serialnumberfield": "SRV-2024-0042-R1",
"costfield": "2500.00"
}
}'curl -X PUT \
'https://glpi.example.com/apirest.php/Ticket/42' \
-H 'Content-Type: application/json' \
-H 'Session-Token: YOUR_SESSION_TOKEN' \
-H 'App-Token: YOUR_APP_TOKEN' \
-d '{
"input": {
"id": 42,
"c_id": 7,
"locationdetailfield": "Building B, Floor 3, Room 301"
}
}'curl -X PUT \
'https://glpi.example.com/apirest.php/Ticket/42' \
-H 'Content-Type: application/json' \
-H 'Session-Token: YOUR_SESSION_TOKEN' \
-H 'App-Token: YOUR_APP_TOKEN' \
-d '{
"input": {
"id": 42,
"urgency": 5
}
}'Updating only native fields will not erase existing plugin field values. Plugin fields are stored in a separate table.
curl -X PUT \
'https://glpi.example.com/apirest.php/Ticket' \
-H 'Content-Type: application/json' \
-H 'Session-Token: YOUR_SESSION_TOKEN' \
-H 'App-Token: YOUR_APP_TOKEN' \
-d '{
"input": [
{ "id": 42, "serialnumberfield": "SN-001" },
{ "id": 43, "serialnumberfield": "SN-002" }
]
}'Single-line text field.
{ "input": { "id": 42, "mytextfield": "Hello World" } }Multi-line plain text field.
{ "input": { "id": 42, "descriptionfield": "Line 1\nLine 2\nLine 3" } }HTML content field. Supports standard HTML tags.
{ "input": { "id": 42, "detailfield": "<p>This is <strong>rich</strong> text</p>" } }Numeric value stored as string. Commas are automatically converted to dots.
{ "input": { "id": 42, "costfield": "1500.50" } }URL field.
{ "input": { "id": 42, "documentationlinkfield": "https://wiki.example.com/kb/12345" } }Date in YYYY-MM-DD format.
{ "input": { "id": 42, "deadlinefield": "2025-12-31" } }Date and time in YYYY-MM-DD HH:MM:SS format.
{ "input": { "id": 42, "scheduledatfield": "2025-06-15 14:30:00" } }Boolean field. 0 = No, 1 = Yes.
{ "input": { "id": 42, "isurgentfield": 1 } }A dropdown specific to the Fields plugin. The value is the ID of the dropdown entry in the plugin's own dropdown table (glpi_plugin_fields_{fieldname}dropdowns).
The API key uses the format: plugin_fields_{fieldname}dropdowns_id
{ "input": { "id": 42, "plugin_fields_criticalityfieldropdowns_id": 3 } }To list available values, query the dynamic class via API:
curl -X GET \ 'https://glpi.example.com/apirest.php/PluginFieldsCriticalityfieldDropdown' \ -H 'Session-Token: YOUR_SESSION_TOKEN' \ -H 'App-Token: YOUR_APP_TOKEN'
A dropdown pointing to an existing GLPI itemtype. The value is the ID of the referenced item.
The API key uses the format: {foreignkey}_{fieldname}
Where {foreignkey} is the standard GLPI foreign key for the itemtype:
User→users_idComputer→computers_idLocation→locations_idGroup→groups_idSupplier→suppliers_id
Example: dropdown-User field (label "Manager")
{ "input": { "id": 42, "users_id_managerfield": 5 } }Example: dropdown-Location field (label "Site")
{ "input": { "id": 42, "locations_id_sitefield": 12 } }Example: dropdown-Computer field (label "Related Asset")
{ "input": { "id": 42, "computers_id_relatedassetfield": 7 } }A polymorphic field that can reference any GLPI item. It requires two keys:
itemtype_{fieldname}— the class name of the referenced itemtypeitems_id_{fieldname}— the ID of the referenced item
{
"input": {
"id": 42,
"itemtype_relateditemfield": "Computer",
"items_id_relateditemfield": 15
}
}Valid itemtype values include any CommonDBTM subclass: Computer, Monitor, NetworkEquipment, Printer, Phone, Software, User, Group, etc.
Plugin fields are registered as search options on the parent itemtype. Use the listSearchOptions endpoint to discover them:
curl -X GET \
'https://glpi.example.com/apirest.php/listSearchOptions/Ticket' \
-H 'Session-Token: YOUR_SESSION_TOKEN' \
-H 'App-Token: YOUR_APP_TOKEN'Fields plugin options appear with IDs starting at 8100+. Example response excerpt:
{
"8101": {
"name": "My Container > Serial Number",
"table": "glpi_plugin_fields_ticketmycontainers",
"field": "serialnumberfield",
"datatype": "string",
"nosearch": false
}
}Then use the searchItems endpoint with forcedisplay to retrieve those values:
curl -X GET \
'https://glpi.example.com/apirest.php/search/Ticket?forcedisplay[0]=1&forcedisplay[1]=2&forcedisplay[2]=8101' \
-H 'Session-Token: YOUR_SESSION_TOKEN' \
-H 'App-Token: YOUR_APP_TOKEN'The dynamically generated container class can be queried directly:
# List all plugin field values for a given container type
curl -X GET \
'https://glpi.example.com/apirest.php/PluginFieldsTicketmycontainer/?searchText[items_id]=42' \
-H 'Session-Token: YOUR_SESSION_TOKEN' \
-H 'App-Token: YOUR_APP_TOKEN'The class name follows the pattern: PluginFields{Itemtype}{containername} (without trailing 's')
Examples:
- Container "Extra Info" on Ticket →
PluginFieldsTicketextrainfo - Container "Asset Details" on Computer →
PluginFieldsComputerassetdetail
Use the search option IDs discovered via listSearchOptions:
# Find tickets where custom field "serialnumberfield" (search option 8101) equals "SRV-2024-0042"
curl -X GET \
'https://glpi.example.com/apirest.php/search/Ticket?criteria[0][field]=8101&criteria[0][searchtype]=equals&criteria[0][value]=SRV-2024-0042&forcedisplay[0]=8101' \
-H 'Session-Token: YOUR_SESSION_TOKEN' \
-H 'App-Token: YOUR_APP_TOKEN'Fields marked as "multiple" accept arrays of IDs:
{
"input": {
"id": 42,
"plugin_fields_tagfieldropdowns_id": [1, 3, 5]
}
}{
"input": {
"id": 42,
"users_id_assignedtofield": [2, 7, 12]
}
}Values are stored as a JSON array internally. On update, by default, the new array replaces the existing values entirely.
Setup assumed:
- Container "Incident Details" (type
dom, id5) onTicketwith fields:referencefield(text)costfield(number)isescalatedfield(yesno)duedatefield(date)plugin_fields_priorityfieldropdowns_id(custom dropdown)users_id_approverfield(dropdown-User)itemtype_relateditemfield+items_id_relateditemfield(glpi_item)
Step 1: Init Session
curl -X GET \
'https://glpi.example.com/apirest.php/initSession' \
-H 'Content-Type: application/json' \
-H 'Authorization: user_token abc123def456' \
-H 'App-Token: YOUR_APP_TOKEN'Step 2: Create Ticket with all custom fields
curl -X POST \
'https://glpi.example.com/apirest.php/Ticket' \
-H 'Content-Type: application/json' \
-H 'Session-Token: YOUR_SESSION_TOKEN' \
-H 'App-Token: YOUR_APP_TOKEN' \
-d '{
"input": {
"name": "Production server failure",
"content": "<p>Server srv-prod-01 is unresponsive since 14:00</p>",
"entities_id": 0,
"type": 1,
"urgency": 5,
"impact": 5,
"referencefield": "INC-2025-0042",
"costfield": "3500.00",
"isescalatedfield": 0,
"duedatefield": "2025-03-05",
"plugin_fields_priorityfieldropdowns_id": 2,
"users_id_approverfield": 5,
"itemtype_relateditemfield": "Computer",
"items_id_relateditemfield": 15
}
}'Step 3: Update — escalate the ticket
curl -X PUT \
'https://glpi.example.com/apirest.php/Ticket/42' \
-H 'Content-Type: application/json' \
-H 'Session-Token: YOUR_SESSION_TOKEN' \
-H 'App-Token: YOUR_APP_TOKEN' \
-d '{
"input": {
"id": 42,
"urgency": 5,
"isescalatedfield": 1,
"plugin_fields_priorityfieldropdowns_id": 4,
"users_id_approverfield": 8
}
}'Step 4: Kill Session
curl -X GET \
'https://glpi.example.com/apirest.php/killSession' \
-H 'Session-Token: YOUR_SESSION_TOKEN' \
-H 'App-Token: YOUR_APP_TOKEN'When your Ticket has:
- A
domcontainer (id5): "Incident Details" withreferencefield - A
tabcontainer (id7): "SLA Info" withslatargetfield
You need two separate update calls:
# Update dom container fields (auto-detected, no c_id needed)
curl -X PUT \
'https://glpi.example.com/apirest.php/Ticket/42' \
-H 'Content-Type: application/json' \
-H 'Session-Token: YOUR_SESSION_TOKEN' \
-H 'App-Token: YOUR_APP_TOKEN' \
-d '{
"input": {
"id": 42,
"referencefield": "INC-2025-0042"
}
}'# Update tab container fields (explicit c_id required)
curl -X PUT \
'https://glpi.example.com/apirest.php/Ticket/42' \
-H 'Content-Type: application/json' \
-H 'Session-Token: YOUR_SESSION_TOKEN' \
-H 'App-Token: YOUR_APP_TOKEN' \
-d '{
"input": {
"id": 42,
"c_id": 7,
"slatargetfield": "2025-03-10 18:00:00"
}
}'When your Ticket has several tab containers, each must be updated with a separate API call using its c_id:
- Tab container "SLA Info" (id
7): fieldsslatargetfield,slastatusfield - Tab container "Finance" (id
9): fieldscostcenterfield,budgetcodefield - Tab container "External Ref" (id
12): fieldsvendorreffield
# Update "SLA Info" tab (c_id = 7)
curl -X PUT \
'https://glpi.example.com/apirest.php/Ticket/42' \
-H 'Content-Type: application/json' \
-H 'Session-Token: YOUR_SESSION_TOKEN' \
-H 'App-Token: YOUR_APP_TOKEN' \
-d '{
"input": {
"id": 42,
"c_id": 7,
"slatargetfield": "2025-03-10 18:00:00",
"slastatusfield": "On Track"
}
}'# Update "Finance" tab (c_id = 9)
curl -X PUT \
'https://glpi.example.com/apirest.php/Ticket/42' \
-H 'Content-Type: application/json' \
-H 'Session-Token: YOUR_SESSION_TOKEN' \
-H 'App-Token: YOUR_APP_TOKEN' \
-d '{
"input": {
"id": 42,
"c_id": 9,
"costcenterfield": "CC-4200",
"budgetcodefield": "BUD-2025-Q1"
}
}'# Update "External Ref" tab (c_id = 12)
curl -X PUT \
'https://glpi.example.com/apirest.php/Ticket/42' \
-H 'Content-Type: application/json' \
-H 'Session-Token: YOUR_SESSION_TOKEN' \
-H 'App-Token: YOUR_APP_TOKEN' \
-d '{
"input": {
"id": 42,
"c_id": 12,
"vendorreffield": "VENDOR-TKT-98765"
}
}'Important: Each API call targets one container only via
c_id. You cannot mix fields from different containers in the same request. If you omitc_idwhen multipletabcontainers exist, the plugin will attempt to auto-detect adomcontainer first, then fall back to the first matchingtab— which may not be the one you intend.
Step 1: List available dropdown values
curl -X GET \
'https://glpi.example.com/apirest.php/PluginFieldsPriorityfieldDropdown?range=0-50' \
-H 'Session-Token: YOUR_SESSION_TOKEN' \
-H 'App-Token: YOUR_APP_TOKEN'Response:
[
{ "id": 1, "name": "Low", "comment": "", "completename": "Low" },
{ "id": 2, "name": "Medium", "comment": "", "completename": "Medium" },
{ "id": 3, "name": "High", "comment": "", "completename": "High" },
{ "id": 4, "name": "Critical", "comment": "", "completename": "Critical" }
]Step 2: Create a new dropdown value
curl -X POST \
'https://glpi.example.com/apirest.php/PluginFieldsPriorityfieldDropdown' \
-H 'Content-Type: application/json' \
-H 'Session-Token: YOUR_SESSION_TOKEN' \
-H 'App-Token: YOUR_APP_TOKEN' \
-d '{
"input": {
"name": "Blocker",
"comment": "Production blocker",
"entities_id": 0,
"is_recursive": 1
}
}'Step 3: Use the value in a ticket
{ "input": { "id": 42, "plugin_fields_priorityfieldropdowns_id": 5 } }- Check plugin version: Ensure you're running Fields plugin ≥ 1.23.3 with the API fix (#1154)
- Check container is active: Disabled containers are ignored
- Check entity visibility: The container must be visible in the entity of the target item
- Check profile rights: The API user's profile must have read/write access to the container in the Fields plugin profile settings
- Check field names: Use
listSearchOptionsto verify the exact field names
This error does not happen — c_id is silently consumed by the plugin and removed from the input before GLPI processes it. If you see unexpected errors, verify the field names are spelled correctly.
curl -X GET \
'https://glpi.example.com/apirest.php/PluginFieldsContainer?range=0-50' \
-H 'Session-Token: YOUR_SESSION_TOKEN' \
-H 'App-Token: YOUR_APP_TOKEN'Look for the id, name, label, type, and itemtypes fields in the response.
curl -X GET \
'https://glpi.example.com/apirest.php/PluginFieldsField?searchText[plugin_fields_containers_id]=5&range=0-50' \
-H 'Session-Token: YOUR_SESSION_TOKEN' \
-H 'App-Token: YOUR_APP_TOKEN'The name column in the response is the base key to use in API calls. For custom dropdown fields, prefix it as plugin_fields_{name}dropdowns_id.