Implementing custom fields
Define and use custom fields to attach domain-specific data to entities.
Navixy Repository API is a work in progress. This documentation is published for preview purposes only and doesn't reflect a stable release. Structure, field names, and behaviors are subject to change.
In Navixy Repository API, devices, assets, geo objects, and schedules each come with a set of built-in fields such as title, organization, and type. Custom fields let you extend these entities with additional data specific to your operation, such as a VIN number, a fuel type, an inspection date, or access level, without any changes to the platform schema.
How custom fields work
Custom fields can be user-defined or predefined. User-defined fields are created by you and scoped to a specific entity type — for example, a vin field that only appears in vehicles. Predefined fields are built into the platform for certain entity types, such as geojson in geo objects.
This guide covers user-defined fields. Avoid using predefined field codes (geojson, device, and schedule_data) for creating your own fields.
Every custom field has a FieldType that determines what kind of data it stores and what validation options are available. You can add any number of fields with different types to a given entity type.
Field type reference
STRING
Short text, codes, identifiers
isRequired, minLength, maxLength, defaultValue, trim
"1HGBH41JXMN109186"
TEXT
Long descriptions, notes
isRequired, maxLength, defaultValue, trim
"Installed under dashboard, driver side"
NUMBER
Quantities, measurements
isRequired, min, max, precision, defaultValue
42, 3.14
BOOLEAN
Flags, yes/no attributes
isRequired, defaultValue
true
DATE
Calendar dates
isRequired, defaultValue
"2025-06-01"
DATETIME
Timestamps
isRequired, defaultValue
"2025-06-01T09:00:00Z"
OPTIONS
Predefined choices (single or multi)
isRequired, isMulti, options[], defaultValue
"diesel"
GEOJSON
Geometry data
isRequired, allowedTypes (GeoJsonGeometryType)
{"type":"Point","coordinates":[...]}
DEVICE
Links to device records
isRequired, isMulti
"019a6a3f-..."
REFERENCE
Links to other entity records
isRequired, isMulti, refEntityTypeCode
"019a6a3f-..."
CATALOG
Links to catalog items
isRequired, isMulti, refCatalogCode
"ITEM_CODE"
TAG
Tags from a tag catalog
isRequired, isMulti
"TAG_CODE"
Each field is described by CustomFieldDefinition — a metadata record that specifies the field's code, display title, type, and validation rules. When you create or update an entity, you supply field values through the customFields field in the mutation input, and the API validates each value against the corresponding definition.
Writing custom field values
customFields in any create or update mutation accepts a CustomFieldsPatchInput with two sub-fields:
This is the patch model: fields you don't mention are left unchanged. You can set and unset in the same mutation. For example, to update a license plate and remove an assigned driver in one call, add this code:
Omitting customFields altogether leaves all existing values untouched.
Scenario: Enriching fleet records with metadata
A logistics company needs to store operational metadata on their vehicle assets: a VIN number for compliance, a fuel type for route planning, and a next service date for maintenance management. All examples in this guide use these three fields.
Adding this metadata requires the following steps:
Choose a field type
Before creating a definition, pick the fieldType that best matches your data. See the field type reference above.
fieldType is immutable after creation. If you need to change a field's type, delete the definition and create a new one. Values already stored under that code in entity records remain in the JSON but will no longer have a backing definition.
Create field definitions
To create a definition, you need three IDs:
organizationId: the organization that owns the definitionownerCatalogItemId: the specific type the field belongs to (e.g.,AssetTypefor "vehicle")targetEntityTypeId: the broader entity type category (e.g.,EntityTypefor "asset")
2.1 Check the existing definitions
Before adding new fields, check what's already defined in a type by querying customFieldDefinitions on the type object:
Response (if the fields already exist):
If no custom fields have been created yet, customFieldDefinitions is an empty array. The query works the same way for deviceType, geoObjectType, and scheduleType.
2.2 Choose codes for your fields
Choose a code for each field before creating its definition. The code becomes the key used to read and write values in all entity mutations and queries, so treat it as stable once records carry values under it — changing it later means recreating the definition and losing existing data.
Codes can contain ASCII letters, digits, underscores, dots, and hyphens, and must start with a letter or digit (max 64 characters). Predefined system items use UPPER_SNAKE_CASE, but user-defined fields accept any valid format.
2.3 Create a STRING field (VIN)
Run the following mutation:
The response confirms creation and returns the definition's ID:
The params input uses the @oneOf directive — you must provide exactly one variant matching your fieldType.
Each field type has its own named params block that you must use. The mutations in this step demonstrate this: the VIN field uses params: { string: { ... } }, the fuel type field uses params: { options: { ... } }, and the service date field uses params: { date: { ... } }. Providing the wrong variant returns a validation error.
2.4 Create an OPTIONS field (fuel type)
Run the following mutation:
On success, the response returns the new definition's id and code.
Set isMulti: true if an entity can support more than one option. See multi-value fields and filtering for how this affects queries.
2.5 Create a DATE field (next service date)
Run the following mutation:
On success, the response returns the new definition's id and code.
The same mutation (customFieldDefinitionCreate) works for devices, geo objects, and schedules — only ownerCatalogItemId, targetEntityTypeId, and the params variant change.
Set and update values
Pass customFields in the create mutation with the initial values under set. The following example creates a vehicle asset with all three fields populated:
The response returns the created asset's id, version, and customFields:
If any custom field value fails validation, the entire mutation is rejected with a VALIDATION_ERROR. Common causes include a value that violates the field's params constraints (for example, a VIN shorter than 17 characters), an unrecognized field code, or a value of the wrong type. The error response includes a field path and a detail message identifying the problem. See Error handling for the full error format.
The same pattern applies to deviceCreate, geoObjectCreate, and scheduleCreate fields.
Update custom field values
Use set to overwrite specific fields and unset to remove them. Fields omitted from both are left unchanged.
The following mutation updates the SIM card number on a device and removes its installation notes:
The response returns the updated device's id, version, and customFields. Fields that were unset no longer appear in the JSON:
All entity update mutations require the current version for optimistic locking. Fetch the entity first if you don't have the latest version.
Read custom field values
customFields on any entity returns a JSON object keyed by field code. By default, all fields are returned. Run the following query:
Response:
To retrieve only specific fields, pass the codes argument. This keeps response payloads smaller when an entity type has many fields:
The response contains only the requested fields:
Filter entities by custom field value
All entity list queries support filtering by custom field values through CustomFieldFilter. Add one or more conditions to the customFields filter array. Multiple conditions are applied as AND.
For the full operator list and value formats by field type, see Filtering and sorting.
How to filter by an OPTIONS value
Find all electric vehicle assets:
Response:
How to filter by a DATE value
Find vehicles with a service date before a deadline:
Response:
How to combine multiple conditions
Find devices with a specific SIM card prefix that don't yet have installation notes:
Response:
Omit value (or set it to null) when using the IS_NULL and IS_NOT_NULL operators.
Managing definitions
How to update a custom field definition
You can update the title, description, order, and params. The code and fieldType cannot be changed after creation. Updates use optimistic locking and require the current version:
The response returns the updated definition's id, incremented version, and new title.
For OPTIONS fields, you can add new options or archive existing ones. Archiving an option (isArchived: true) hides it from new selections without affecting records that already carry it:
How to delete a custom field definition
Run this mutation:
The response returns the ID of the deleted definition:
Deleting a definition removes its key from the customFields JSON on all entity records. If you create a new definition with the same code later, existing records will not retain any value for it — the data is not preserved.
Constraints and considerations
Keep in mind the following:
Validation errors reject the entire mutation: Mutations that include invalid custom field values are rejected in full. See Error handling for the error format.
fieldTypeis immutable: To change a field's type, delete its definition and create a new one. Deleting the definition removes its values from all entity records.codeis stable once in use:codemust be unique within the owner type and organization. As this is the key used to read and write values across all entity mutations and queries, avoid recreating it under a different name if records contain values paired with it.paramsrequires exactly one variant:FieldParamsInputuses the@oneOfdirective, so you must provide exactly the variant that matches yourfieldType. Providingstring: { ... }whenfieldTypeisNUMBERreturns a validation error.Multi-value fields and filtering: For fields with
isMulti: true, a filter matches if any value in the array satisfies the condition. For example, if an asset hasfuel_type: ["diesel", "hybrid"], filtering withEQ: "diesel"will match it.Predefined fields: Predefined definitions (like
geojsonandschedule_data) are platform-managed and appear incustomFieldsresponses alongside your definitions. Do not use codes that conflict with predefined field codes.
See also
Custom fields types and operations: A complete list of all operations and types related to custom fields
Filtering and sorting: Full operator reference and value formats for custom field filters
Optimistic locking: How
versionworks in update and delete mutations
Last updated
Was this helpful?