The Zendesk REST API provides many types of native data objects for storing and managing your customer data, including tickets, users, and organizations. We call these "standard objects." However, standard objects can't provide every possible type of data object that your organization might want. Admins can create custom objects to capture, model, and retrieve data that doesn't fit into the standard Zendesk objects. Extending the Zendesk data model with custom objects enables you to seamlessly integrate your custom data with tickets, triggers, Explore analytics, integrations, and the Zendesk Apps framework. Zendesk provides fully functional Custom Object APIs, but custom objects can also be used without any coding.

Creating a custom object consists of two parts: defining the object itself and then adding custom fields to the object to create the object's schema.

Creating custom objects

Technically, a custom object consists of a name, a key, and custom fields. The name and key are used to identify the object, and the fields create the schema of attributes for the object. The fields describe the information you can collect for this type of object.

To create a custom object

  1. Work with your admins to Turn on custom objects and Plan your custom objects workflow.

  2. Use the create custom object endpoint to create the object: POST /api/v2/custom_objects. In this request you'll specify the objects key, title, and title_pluralized values. The key will be used in all other requests related to the object.

  3. Use the create custom object field endpoint to add fields to the custom object: POST /api/v2/custom_objects/{custom_object_key}/fields, where {custom_object_key} is replaced with the key you specified when creating the object. In the request, you'll specif the field's key, title, type, and other details required by the field type. Agents will see the fields in the order they are created unless you use the reorder custom fields of an object endpoint to specify an array of custom object field ids in the preferred order.

  4. Add lookup relationship fields to connect the custom object to other objects in your Zendesk account. Lookup relationship fields are a type of custom field that defines one-to-many relationships and can be defined on standard Zendesk objects (tickets, users, and organizations) or custom objects. You might need to define the lookup field on another object and point it to your custom object. For example, you'll probably want to define new ticket lookup fields that point to your custom objects so agents can associate custom object records with tickets.


Let's walk through what these steps might look like if you want to use custom objects in Zendesk to manage software and license assets as an IT organization. For this example, let's assume custom objects is already enabled for your account.

Step 1: Planning your workflow

Your admin decided you need a two custom objects: one for software and another for licenses. The admin provides the following spreadsheets:

Custom object name: Software

Field NameField TypeValues
Software namestandard: Name
OS compatibilityDrop-downAll, Windows, MacOS
Needs approval?Checkbox
StatusDrop-downPending, Approved, Not Approved

Custom object name: License

Field NameField TypeValues
License keystandard: Name
SoftwareLookup > Software
StatusDrop-downAssigned, Active, Expired
Assigned toLookup > Users

Additionally, your admin requests that you add two new lookup relationship fields to the ticket form as well:

  • Software requested: Points to the Software object, but needs a filter to only allow selection of software records with a status of Approved.
  • License assigned: Points to the License object.

Based on is information, you determine that you need to create two custom objects, each with several custom fields, and two new ticket fields.

Step 2: Creating your objects

Start by creating your custom objects with the POST /api/v2/custom_objects endpoint. In the request body, specify the following parameters:

  • A key for the custom object. This must be unique and can't be changed. Object keys are used in all subsequent requests related to the object.
  • A title or singular name for the custom object.
  • A title_pluralized or plural name for the custom object. This is displayed to agents on the Custom object records page in Support.

The following request creates a custom object named Software:

curl --request POST https://{subdomain} \--header "Content-Type: application/json" \-u {username}:{password} \--data-raw '{  "custom_object": {    "key": "software",    "title": "Software",    "title_pluralized": "Software"  }}'

You should see a response similar to this:

// Status 201 Created
{    "custom_object": {        "url": "https://{subdomain}",        "key": "software",        "created_by_user_id": "15590417147927",        "updated_by_user_id": "15590417147927",        "created_at": "2023-09-12T16:28:17Z",        "updated_at": "2023-09-12T16:28:17Z",        "title": "Software",        "raw_title": "Software",        "title_pluralized": "Software",        "raw_title_pluralized": "Software",        "description": "",        "raw_description": ""    }}

Then, use the same request with an adjusted request body to create the license object.

'{  "custom_object": {    "key": "license",    "title": "License",    "title_pluralized": "Licenses"  }}'

Step 3: Defining your custom object's schema with fields

After you create your two new objects, you need to add custom fields to them. For the purposes of this example, we'll walk through a few different types of custom fields the admin requested for the software and license objects, but not all of them. For more information, see Custom Object Fields.

Update the standard name field

First, you recognize that your admin wants to modify the standard Name field for both of your custom objects. To do this, you'll use the PATCH /api/v2/custom_objects/{custom_object_key}/fields endpoint and specify standard::name as the field key in your request. For example:

curl --request PATCH https://{subdomain} \--header "Content-Type: application/json" \-u {username}:{password} \-d '{  "custom_object": {    "title": "Software name",  }}'

You should see a Status 200 OK response, with the updated title value visible.

Add a checkbox field

To add a checkbox field, use the POST /api/v2/custom_objects/{custom_object_key}/fields endpoint, but this tume you only need to speciy the key, title, and type. For example:

curl --request PATCH https://{subdomain} \--header "Content-Type: application/json" \-u {username}:{password} \-d '{	"custom_object_field": {		"key": "needs_approval",		"title": "Approval required",		"type": "checkbox"	}}'

The response will return details about the field, similar to this:

// Status 201 Created
{  "custom_object_fields": [    {      "url": "https://{subdomain}",      "id": 17469587590423,      "type": "checkbox",      "key": "needs_approval",      "title": "Approval required",      "description": "",      "raw_title": "Approval required",      "raw_description": "",      "position": 2,      "active": true,      "system": false,      "regexp_for_validation": null,      "created_at": "2023-09-12T17:23:12Z",      "updated_at": "2023-09-12T17:49:34Z",      "tag": null    }  ]}

Add a dropdown field

Both objects require dropdown custom fields. To create the Status dropdown field for the software object, use the POST /api/v2/custom_objects/{custom_object_key}/fields endpoint. In the request body, use the custom_field_options property to define an array of JSON objects for each option. Each option you define for the dropdown consists of a name, which is the value agents will select when interacting with the field, and a value with reflects the tag associated with the dropdown option. For example:

curl --request PATCH https://{subdomain} \--header "Content-Type: application/json" \-u {username}:{password} \-d '{    "custom_object_field": {        "title": "Status",        "key": "approval_status",        "type": "dropdown",        "custom_field_options": [            {                "name": "approved",                "value": "Approved"            },            {                "name": "denied",                "value": "Not_approved"            },            {                "name": "pending",                "value": "Pending"            }        ]    }}'

You should see a response similar to when you created the checkbox field. However, the response will also include id's for each dropdown option you defined.

Continue adding and updating fields for ou custom objects until you've created the object schema your admins requested.

Step 4: Connecting your object with lookup relationship fields

Now it's time to complete your data model connecting your custom objects to other objects in your account. Use lookup relationship fields to define how the custom object relates to standard Zendesk objects (users, organizations, and tickets) and other custom objects. A lookup relationship can be described as source object -> related object. The source object is the Zendesk object that contains the lookup relationship field (among other fields). The related object is the object specified by the lookup relationship field.

Adding related objects doesn't automatically create an association between two specific records. Instead, it describes the relationship and enables agents to associate records this way.

If you want the custom object to contain the relationship, add it as a custom field on your object. Alternatively, if you'd prefer a different object, such as tickets, to include a field related to your custom object, add the lookup field to that object instead.

In this example, your admins requested lookup fields defined on the license object as well as new ticket lookup fields that point to the custom objects. The endpoints used to create these lookup relationship fields will vary by the type of object you're adding the field to, but the request body will be very similar in all cases. Regardless of the object you're adding the custom object to, you'll need to specify a type, title, and relationship_target_type, which identifies the target object. For lookup fields that point to a custom object, use zen:custom_object:CUSTOM_OBJECT_KEY to specify the object; to point to standard objects, use zen: user, zen:organization, or zen:ticket. Optionally, you can also include any relationship_filter you want to apply to the lookup field; filters on lookup fields restrict which records can be selected when setting a value in the lookup field.

Add a lookup relationship field to a custom object

Like all other custom object fields, lookup fields on custom objects require a key. Otherwise, the body request should look like the request to create a lookup field on any other object type.

Going back to our example, one of the admin's requests was a lookup field on the License object that points to the Software object. The request to create this lookup field might look like this:

curl --request POST https://{subdomain} \--header "Content-Type: application/json" \-u {username}:{password} \--data-raw '{  "custom_object_field": {     "key": "software",    "title": "Software",    "type": "lookup",    "relationship_target_type": "zen:custom_object:software"     }}'

In response you'll see details about the lookup relationship field similar to this:

// Status 201 Created
{    "custom_object_field": {        "url": "https://{subdomain}",        "id": 17531163245847,        "type": "lookup",        "key": "software",        "title": "Software",        "description": "Software",        "raw_title": "Software",        "raw_description": "Software",        "position": 9999,        "active": true,        "system": false,        "regexp_for_validation": null,        "created_at": "2023-09-14T18:03:08Z",        "updated_at": "2023-09-14T18:03:08Z",        "relationship_target_type": "zen:custom_object:software"    }}

Add a lookup relationship field to a ticket

Similar to the above example, the admin also requested new lookup fields on tickets that point to the custom objects. To create lookup fields on tickets, use the POST /api/v2/ticket_fields.json endpoint. There's no need to specify a key for custom ticket fields, but you will need to include "relationship_target_type": "zen:custom_object:software” again. The following example shows how to create a ticket lookup field named Software requested, which points to your Software custom object, and only permits the selection of software records with a status of Approved. To filter the available values, you need to reference the field using the following format: custom_object.CUSTOM_OBJECT_KEY.custom_fields.CUSTOM_OBJECT_FIELD_KEY. In this case, the referenced field is a dropdown field, so you'll need to use the dropdown option's id as the value.

curl https://{subdomain} \-H "Content-Type: application/json" -X POST \-u {email_address}:{password} \--data-raw '{    "ticket_field": {        "type": "lookup",        "title": "Software requested",        "relationship_target_type": "zen:custom_object:software",        "relationship_filter": {            "all": {                "field": "",                "operator": "is",                "value": "17530338458391"            }        }    }}'

In response you'll see details about the lookup relationship field. Ticket fields don't have user-defined key values, so the system-generated id when the field is created is the only way to reference the field. For example:

// Status 201 Created
{    "url": "https://{subdomain}",    "id": 17531702893847,    "type": "lookup",    "title": "Software requested",    "raw_title": "Software requested",    "description": "",    "raw_description": "",    "position": 9999,    "active": true,    "required": false,    "collapsed_for_agents": false,    "regexp_for_validation": null,    "title_in_portal": "Software requested",    "raw_title_in_portal": "Software requested",    "visible_in_portal": false,    "editable_in_portal": false,    "required_in_portal": false,    "tag": null,    "created_at": "2023-09-14T18:17:03Z",    "updated_at": "2023-09-14T18:17:03Z",    "removable": true,    "key": null,    "agent_description": null,    "relationship_target_type": "zen:custom_object:software",    "relationship_filter": {        "all": [            {                "field": "",                "operator": "is",                "value": "17530338458391"            }        ],        "any": []    }}

Next steps

After you've created your custom objects and created lookup relationship fields to connect them to other objects in Zendesk, let your admin know. At this point, they may want to perform a bulk import of custom object records. When records exist for the custom object, your admin can report on custom object data in lookup relationship fields. See Reporting with custom fields. Both bulk importing custom object records and Explore reporting can only be done in Admin Center.

As a developer, the next step you might be asked to help with is integrating custom objects into triggers. For more information about this, see [Using custom objects in triggers][/documentation/custom-data/v2/using-custom-objects-in-triggers].